from odoo import models, fields, api,_ from odoo.exceptions import UserError, ValidationError,Warning from psycopg2 import sql, DatabaseError from werkzeug import utils import json class opendons_aggregate_partner(models.Model): _name = 'opendons.aggregate.partner' _description = 'opération marketing : partner agregats' partner_id = fields.Many2one('res.partner',string='partner',readonly=True) first_donation_product_id=fields.Many2one('product.product',string='first donation product affectation',readonly=True) first_donation_date=fields.Date(string='first donation date', readonly=True) first_donation_operation_id = fields.Many2one('opendon.operation',string='first donation operation',readonly=True) max_amount_donation=fields.Float(string='max amount donation',readonly=True) annual_average_number_donation=fields.Float(string='annual average number of donation',readonly=True) average_amount_donation=fields.Float(string='average amount donation',readonly=True) rfm_score=fields.Float(string='rfm score',readonly=True) def compute_aggregate(self): self._compute_init() partners=self.env['res.partner'].search([]) for partner in partners: vals={} vals['partner_id']=int(partner.id) vals['first_donation_product_id']=self._compute_first_donation_product(partner.id) #first_donation_date=self._compute_first_donation_date(partner.id) vals['first_donation_date']=self._compute_first_donation_date(partner.id) vals['first_donation_operation_id']=self._compute_first_donation_operation(partner.id) vals['max_amount_donation']=self._compute_max_amount_donation(partner.id) vals['annual_average_number_donation']=self._compute_annual_average_number_donation(partner.id) vals['average_amount_donation']=self._compute_average_amount_donation(partner.id) #vals['rfm_score']=self._compute_rfm_score(partner_id)) res=self.env['opendons.aggregate.partner'].create(vals) partner.aggregate_id=res.id def _compute_init(self): aggregate=self.env['opendons.aggregate.partner'].search([]) aggregate.unlink() return True def _compute_first_donation_product(self,partner_id): first_donation=self.env['donation.donation'].search([('partner_id','=',int(partner_id)),('recurring_template','=',False),('state','=','done')],limit=1,order="donation_date asc") if first_donation: first_line_donation=self.env['donation.line'].search([('donation_id','=',int(first_donation.id))],limit=1,order="id asc") if first_line_donation: return int(first_line_donation.product_id) return False def _compute_first_donation_operation(self,partner_id): first_donation=self.env['donation.donation'].search([('partner_id','=',int(partner_id)),('recurring_template','=',False),('state','=','done')],limit=1,order="donation_date asc") if first_donation: return int(first_donation.operation_id) else: return False def _compute_first_donation_date(self,partner_id): first_donation=self.env['donation.donation'].search([('partner_id','=',int(partner_id)),('recurring_template','=',False),('state','=','done')],limit=1,order="donation_date asc") if first_donation: return first_donation.donation_date else: return False def _compute_max_amount_donation(self,partner_id): donation=self.env['donation.donation'].search([('partner_id','=',int(partner_id)),('recurring_template','=',False),('state','=','done')],limit=1,order="amount_total desc") if donation: return donation.amount_total else: return False return True def _compute_annual_average_number_donation(self,partner_id): annual_donation= self.env['donation.donation'].read_group([('partner_id','=',int(partner_id))], fields=['year_donation_date','partner_id:count'], groupby=['year_donation_date'],lazy=False) if annual_donation: i=0 total=0 for l in annual_donation: total=total+l['partner_id'] i=i+1 return total/i else: return 0 return True def _compute_average_amount_donation(self,partner_id): donation=self.env['donation.donation'].search([('partner_id','=',int(partner_id)),('recurring_template','=',False),('state','=','done')]) if donation: i=0 amount=0 for d in donation: amount=amount+d.amount_total i=i+1 return amount/i else: return 0 def _compute_rfm_score(self,partner_id): # Score RFM = Récence * (poids accordé à la Récence) # + Fréquence * (poids accordé à la Fréquence) # + Montant * (poids accordé au Montant) # recency #3-12 months since last donation (Rate them as 5 on your recency score) #13-24 months since last donation (Rate them as 4 on your recency score) #25-36 months since last donation (Rate them as 3 on your recency score) #37-48 months since last donation (Rate them as 2 on your recency score) #>49 and over since last donation Rate them as 1 on your recency score) #frequency #Donated between 21 to 25 times during the last 25 solicited (Rate them as 5 on your frequency score) #Donated 16 to 20 times during the last 25 solicited (Rate them as 4 on your frequency score) #Donated 11 to 15 times during the last 25 solicited (Rate them as 3 on your frequency score) #Donated 6 to 10 times during the last 25 solicited (Rate them as 2 on your frequency score) #Donated 1 to 5 times during the last 25 solicited (Rate them as 1 on your frequency score) #the highest donation amount (monetary value) each donor gave each time, #breaking them up into 5 categories in the last 5 years return True