From 5400cda7eef04a2cbd1e8f540bb71df3d3bd7a62 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 20 Feb 2022 09:52:48 +0000 Subject: [PATCH] operations : export des contacts 03:00 --- models/operation.py | 197 +++++++++++++++++++++++++++++++---- models/partner.py | 4 + security/ir.model.access.csv | 2 + views/operation.xml | 3 +- 4 files changed, 183 insertions(+), 23 deletions(-) diff --git a/models/operation.py b/models/operation.py index f1b89e2..7772b46 100644 --- a/models/operation.py +++ b/models/operation.py @@ -9,6 +9,7 @@ import xlwt from io import BytesIO import base64 import csv +import os,secrets _logger = logging.getLogger(__name__) @@ -33,7 +34,9 @@ class opendons_operation(models.Model): partner_count = fields.Integer(string="count",readonly=True) #begin_date=fields.Date(string='Date begin',required=True, translate=True,track_visibility='always') #end_date=fields.Date(string='Date end',required=True, translate=True,track_visibility='always') - + partner_ids = fields.Many2many('res.partner', 'partner_operation_rel', 'partner_id', 'operation_id', string='partners') + #contacts exclus de l'opération + partner_excl_ids=fields.Many2many('res.partner', 'partner_excl_operation_rel', 'partner_id', 'operation_id', string='excluded partners') chanel=fields.Selection([ ('mail', 'Mailing'), ('email', 'E-mailing'), @@ -93,9 +96,6 @@ class opendons_operation(models.Model): ) - - - csv_export = fields.Binary('csv export', filters='.csv', readonly=True) document_fname=fields.Char() @@ -133,35 +133,162 @@ class opendons_operation(models.Model): def csv_export_operation(self): - - with open('export.csv', mode='w') as file: + tmstp=secrets.token_hex(16) + csv_filename='/tmp/export_'+tmstp+'.csv' + with open(csv_filename, mode='w') as file: writer = csv.writer(file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) - # ggcreate a row containds heading of each column - - writer.writerow(['name', 'email']) - # fetch products and write respective data. - partners = self.select_partner_operation() + - for p in partners: - name=p.name - email=p.email - writer.writerow([name,email]) + writer.writerow(['id','key','name', 'email','operation','segment']) + + #sélections des contacts + res=self.select_partner_operation() - with open('export.csv', 'r', encoding="utf-8") as f2: + segments=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=',False)]) + + #extraction des contacts sélectionnés sur chaque segment + for seg in segments: + if seg.partner_ids: + for p in seg.partner_ids: + #raise UserError(p) + id=p.id + key=p.key + name=p.name + email=p.email + operation=int(self.id) + segment=int(seg.id) + writer.writerow([id,key,name,email,operation,segment]) + + with open(csv_filename, 'r', encoding="utf-8") as f2: # file encode and store in a variable ‘data’ data = str.encode(f2.read(), 'utf-8') self.csv_export=base64.encodestring(data) self.document_fname='operation'+str(self.id)+'.csv' - + os.unlink(csv_filename) return - #def select_partner_operation(self): + + def select_partner_operation(self): + + # suppression selections précédemment calculées sur l'opération + self.partner_ids=False + self.partner_excl_ids=False + + #suppression des selections précédemment calculées sur sur les segments + segments=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=',False)]) + for seg in segments: + seg.partner_ids=False + + segexcl=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=',True)]) + segments=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=',False)],order='sequence asc') + + #[["id","not in",[1,3,7,8,10]]] + #["&",["id","not in",[22]],["id","not in",[1,3,7,8,10]]] + # partner_excl=self.env['res.partner'].search(eval(segexcl.mailing_domain)) + # raise UserError(str(partner_excl)) + # str_excl="[" + # i=1 + # for p in partner_excl: + # if i==1: str_excl=str_excl+str(p.id) + # if i>1 : str_excl=str_excl+','+str(p.id) + # str_excl=str_excl+']' + # excl_domain='["id","not in"',+str_excl +']' + #List of Domain operators: ! (Not), | (Or), & (And) + #List of Term operators: '=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of' + + #excl_domain='[("operation_excl_ids","!=","'+self.id+"')]" + i=1 + + for sg in segments: + if i==1: + + mailing_domain='["&","!",'+segexcl.mailing_domain[1:-1]+','+ sg.mailing_domain[1:-1]+']' + + #["&","!",["id","=",1],["id","=",2]] + #["&","!",[["id","=",1]],[["id","=",1]]] + #raise UserError(str(mailing_domain)) + #try: + partners=self.env['res.partner'].search(eval(mailing_domain)) + #except: + # raise UserError(mailing_domain) + + #ajouts des contact à l'opération + self.partner_ids=partners + #ajouts des contacts au segment + sg.partner_ids=partners + #sg_1=sg + else: + #on doit exclure tous les contacts qui pourraient être dans les segments précédent + sg_up=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('sequence','<',int(sg.sequence))]) + if len(sg_up)>1: + str_domain='"&",' + j=1 + for s in sg_up: + if j==1: + str_domain=str_domain + s.mailing_domain[1:-1] + else: + str_domain= '"&",' + str_domain & s.mailing_domain[1:-1] + j=j+1 + str_domain=str_domain+',' + else: + str_domain='' + + #mailing_domain='["&","!","&",'+segexcl.mailing_domain[1:-1]+','+ sg_1.mailing_domain[1:-1]+',' +sg.mailing_domain[1:-1]+']' + mailing_domain='["&","!",'+str_domain+ segexcl.mailing_domain[1:-1]+',' +sg.mailing_domain[1:-1]+']' + #raise UserError(str_domain) + partners=self.env['res.partner'].search(eval(mailing_domain)) + #ajouts des contact à l'opération + self.partner_ids=partners + #ajouts des contacts au segment + sg.partner_ids=partners + sg_1=sg + + i=i+1 + + + return True + + def select_partner_operation_old(self): #le principe est de selectionner les contacts associés aux segments avec les règles suivantes : - #RG1: si un contact est présent dans un segment d'exclusion, alos on le retire de la sélection - #RG2: la priorité des segments est l'ordre de présentation dans la liste des segmments - #RG3: au final, un contact sélectionné est rattaché à l'opération avec le segment d'appartenance + #RG1: la priorité des segments est l'ordre de présentation dans la liste des segments + #RG2: au final, un contact sélectionné est rattaché à l'opération avec le segment d'appartenance + #RG1: si un contact est présent dans un segment d'exclusion, alors on le retire de la sélection operateur "!"" + + #suppression des contacts déjà présents pour l'opération + self.env["opendons.operation_partner"].search([('operation_id','=',self.id)]).unlink() + + segments=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=','False')],order='sequence asc') + i=1 + for sg in segments: + if i==1: + partners=self.env['res.partner'].search(eval(sg.mailing_domain)) + for p in partners: + vals={} + vals['operation_id']=self.id + vals['segment_id']=sg.id + vals['partner_id']=p.id + + res2=self.env['opendons.operation_partner'].create(vals) + + if i>1: + partners=self.env['res.partner'].search(eval(sg.mailing_domain)) + for p in partners: + pp=self.env["opendons.operation_partner"].search_count( + ['&',('operation_id','=',int(self.id)), + ('partner_id','=',int(p.id))]) + if pp==0: + vals={} + vals['operation_id']=self.id + vals['segment_id']=sg.id + vals['partner_id']=p.id + + + res2=self.env['opendons.operation_partner'].create(vals) + i=i+1 + + return self.env["opendons.operation_partner"].search([('operation_id','=',self.id)]) @api.model def create(self,vals): @@ -203,6 +330,29 @@ class opendons_operation(models.Model): self.document_fname='operation'+seld.id+'.csv' return +class opendons_operation_partner(models.Model): + _name = 'opendons.operation_partner' + _description = 'opération marketing : lignes des contacts sélectionnés et exportés' + + operation_id = fields.Many2one( + 'opendons.operation', + String='Operation', + index=True, + readonly=True) + + segment_id = fields.Many2one( + 'opendons.segment', + String='Segemnt', + index=True, + readonly=True) + + partner_id = fields.Many2one( + 'res.partner', + String='Partner', + index=True, + readonly=True) + + class opendons_segment(models.Model): _name = 'opendons.segment' @@ -216,6 +366,7 @@ class opendons_segment(models.Model): cost = fields.Monetary( string='Cost', currency_field='currency_id') + partner_ids = fields.Many2many('res.partner', 'partner_segment_rel', 'partner_id', 'segment_id', string='partners') partner_count = fields.Integer(string="partners count", compute='_count_partner_segment',readonly=True) mailing_domain = fields.Char(string='partners selection', readonly=True) @@ -241,7 +392,7 @@ class opendons_segment(models.Model): readonly=True, track_visibility='onchange', ondelete='cascade' - ) + ) ensemble_ids = fields.One2many( 'opendons.ensemble', @@ -320,6 +471,8 @@ class opendons_ensemble(models.Model): logical_operator = fields.Selection([('union','union'),('inter','intersection')],'Type',default='union') mailing_domain = fields.Char(string='partners selection', readonly=True) partner_count = fields.Integer(string="partners count",compute='_count_partner_ensemble',readonly=True) + #partner_ids = fields.Many2many('res.partner', 'partner_segment_rel', 'partner_id', 'segment_id', string='partners') + sequence = fields.Integer(string="sequence", default=10) segment_id = fields.Many2one( 'opendons.segment','Segment', diff --git a/models/partner.py b/models/partner.py index b0f6e70..cca2b41 100644 --- a/models/partner.py +++ b/models/partner.py @@ -89,6 +89,10 @@ class partner(models.Model): # readonly=True # ) request_ids = fields.Many2many('opendons.request', 'request_partner_rel', 'partner_id', 'request_id', string='requests') + operation_ids = fields.Many2many('opendons.operation', 'operation_partner_rel', 'partner_id', 'operation_id', string='operations') + operation_excl_ids = fields.Many2many('opendons.operation', 'operation_excl_partner_rel', 'partner_id', 'operation_id', string='excluded operations') + segment_ids = fields.Many2many('opendons.segment', 'segment_partner_rel', 'partner_id', 'segment_id', string='segments') + address_count = fields.Integer( compute='_compute_address_count', diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 6fe99fb..8219c57 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -4,6 +4,8 @@ access_opendons_qualifier_category,opendons_qualifier.category,model_opendons_qu access_opendons_qualifier_partnerqualifier,opendons_qualifier.partnerqualifier,model_opendons_qualifier_partnerqualifier,donation.group_donation_manager,1,1,1,1 access_opendons_partneraddress,opendons.partneraddress,model_opendons_partneraddress,donation.group_donation_manager,1,1,1,1 access_opendons_operations,opendons.operations,model_opendons_operation,donation.group_donation_manager,1,1,1,1 +access_opendons_operation_partner,opendons.operation_partner,model_opendons_operation_partner,donation.group_donation_manager,1,1,1,1 + access_opendons_segments,opendons.segments,model_opendons_segment,donation.group_donation_manager,1,1,1,1 access_opendons_ensembles,opendons.ensembles,model_opendons_ensemble,donation.group_donation_manager,1,1,1,1 access_opendons_requests,opendons.requests,model_opendons_request,donation.group_donation_manager,1,1,1,1 diff --git a/views/operation.xml b/views/operation.xml index b42a97f..6543d0c 100644 --- a/views/operation.xml +++ b/views/operation.xml @@ -148,6 +148,7 @@ +