diff --git a/models/__init__.py b/models/__init__.py index 54f0b22..dc9229c 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -7,6 +7,9 @@ from . import address from . import email from . import phone from . import operation +from . import operation_segment +from . import operation_ensemble +from . import operation_request from . import relationship from . import returnmail from . import payment_batch diff --git a/models/operation.py b/models/operation.py index 4fb83ae..444e9d8 100644 --- a/models/operation.py +++ b/models/operation.py @@ -13,16 +13,6 @@ import os,secrets _logger = logging.getLogger(__name__) -# MASS_MAILING_BUSINESS_MODELS = [ -# 'crm.lead', -# 'event.registration', -# 'hr.applicant', -# 'res.partner', -# 'event.track', -# 'sale.order', -# 'mailing.list', -# 'mailing.contact' -# ] class opendons_operation(models.Model): _name = 'opendons.operation' @@ -34,7 +24,6 @@ class opendons_operation(models.Model): name=fields.Char(string='Name',required=True, translate=True,copy=False,default='campagne',track_visibility='always') partner_count = fields.Integer(string="count",readonly=True) exported_date=fields.Date(string='Exported Date',track_visibility='always', readonly=True) - #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 company_id = fields.Many2one( @@ -58,6 +47,7 @@ class opendons_operation(models.Model): cost = fields.Monetary( string='Cost', currency_field='currency_id') + quantity = fields.Integer(string="quantity",readonly=True) @api.model def _default_currency(self): @@ -107,6 +97,13 @@ class opendons_operation(models.Model): csv_export = fields.Binary('csv export', filters='.csv', readonly=True) document_fname=fields.Char() + batch_export_ids = fields.One2many( + 'opendons.operation.batch_export', + 'operation_id', + string='batchs export', + + ) + def validate(self): @@ -199,9 +196,6 @@ class opendons_operation(models.Model): 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') - - - i=1 @@ -239,9 +233,9 @@ class opendons_operation(models.Model): 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 @@ -279,7 +273,11 @@ class opendons_operation(models.Model): return res - + def unlink(self): + if self.state=='exported': raise UserError(_('it is impossible to delete the operation because his state is \'exported\'')) + donation=self.env['donation.donation'].search([('operation_id','=',int(self.id))]) + if donation:raise UserError(_('it is impossible to delete the operation because there are donations linked')) + return super(opendons_operation,self).unlink() @@ -354,39 +352,12 @@ class opendons_operation(models.Model): #rtn=super(opendons_operation,self).copy(default=default_values) return dup_operation - - -class opendons_segment(models.Model): - _name = 'opendons.segment' - _description = 'operation marketing segment : a segment is a part of contacts selected for an operation ' - _inherit = ['mail.thread'] - sequence = fields.Integer(string="sequence", default=10) - #code=fields.Char(string='Code',required=True, translate=True,track_visibility='always') - name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') - exclusion=fields.Boolean(String='segment d\'exclusion',default=False,readonly=True) - logical_operator = fields.Selection([('union','union'),('inter','intersection')],'Type',default='union') - 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') - - @api.model - def _default_currency(self): - company = self.env['res.company']._company_default_get( - 'opendons.segment') - return company.currency_id - - currency_id = fields.Many2one( - 'res.currency', - string='Currency', - required=True, - track_visibility='onchange', - ondelete='restrict', - default=_default_currency - ) +class opendons_operation_batch_export(models.Model): + _name = 'opendons.operation.batch_export' + _description = 'lot export' + + name=fields.Char(string='Name',required=True,track_visibility='always') operation_id = fields.Many2one( 'opendons.operation', String='Operation', @@ -395,478 +366,5 @@ class opendons_segment(models.Model): track_visibility='onchange', ondelete='cascade' ) - - ensemble_ids = fields.One2many( - 'opendons.ensemble', - 'segment_id', - string='Ensemble', - required=True, - track_visibility='onchange') - - ensemble_count = fields.Integer( - compute='_compute_ensemble_count', - string="# of ensemble", - readonly=True - ) - chanel=fields.Selection([ - ('mail', 'Mailing'), - ('email', 'E-mailing'), - ('event', 'Event'), - ('face_to_face', 'Face to face')], - string='Chanel',required=True, translate=True,track_visibility='always') - - @api.depends('mailing_domain') - def _count_partner_segment(self): - for rec in self: - if rec.mailing_domain : - rec.partner_count=self.env['res.partner'].search_count(eval(rec.mailing_domain)) - else: - rec.partner_count=0 - - def _compute_ensemble_count(self): - # The current user may not have access rights for donations - for segment in self: - try: - segment.ensemble_count = len(segment.ensemble_ids) - except Exception: - segment.ensemble_count = 0 - - @api.model - def create(self,vals): - - - res=super(opendons_segment, self).create(vals) - #segment=self.env['opendons.segment'].search([('id','=',int(res.id))]) - operation=self.env['opendons.operation'].search([('id','=',int(res.operation_id))]) - #_logger.error('segment.id='+str(res.operation_id)) - __last_update=fields.Date.context_today(self) - operation.write( - { - 'segment_count':len(operation.segment_ids), - '__last_update':__last_update - } - ) - - return res - def write(self,vals): - - res=super(opendons_segment, self).write(vals) - mailing_domain=False - for val in vals: - if val=='logical_operator': - - mailing_domain=self.env['opendons.ensemble'].update_segment_domain(self) - - if mailing_domain: - vals['mailing_domain']=mailing_domain - - - - res=super(opendons_segment, self).write(vals) - - operation=self.env['opendons.operation'].search([('id','=',int(self.operation_id))]) - __last_update=fields.Date.context_today(self) - operation.write({'__last_update':__last_update}) - - def copy(self,default_values=None): - - vals={} - vals['name']='copy of ' + self.name - vals['operation_id']=int(self.operation_id) - vals['mailing_domain']=self.mailing_domain - dup_segment=super(opendons_segment, self).create(vals) - - #on duplique les ensembles du segment - for ensemble_id in self.ensemble_ids: - #raise Warning(segment_id.id) - ens=self.env['opendons.ensemble'].search([('id','=',int(ensemble_id.id))]) - - if ens: - vals3={} - vals3['segment_id']=dup_segment.id - vals3['name']=ens.name - vals3['mailing_domain']=ens.mailing_domain - #dup_segment=super(opendons_segment,self).create(vals2) - dup_ensemble=self.env['opendons.ensemble'].create(vals3) - dup_segment.write({'ensemble_ids':[(4,dup_ensemble.id)]}) - - for request_id in ens.request_ids: - req=self.env['opendons.request'].search([('id','=',int(request_id.id))]) - if req: - vals4={} - vals4['ensemble_id']=dup_ensemble.id - vals4['name']=req.name - vals4['mailing_domain']=req.mailing_domain - #dup_segment=super(opendons_segment,self).create(vals2) - dup_request=self.env['opendons.request'].create(vals4) - dup_ensemble.write({'request_ids':[(4,dup_request.id)]}) - - #rtn=super(opendons_operation,self).copy(default=default_values) - - return dup_segment - -class opendons_ensemble(models.Model): - _name = 'opendons.ensemble' - _description = 'operation marketing ensemble : an ensemble is a part of contacts selected for an segment ' - _inherit = ['mail.thread'] - - name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') - logical_operator = fields.Selection([('union','union'),('inter','intersection')],'Type',default='union') - mailing_domain = fields.Char(string='partners selection') - 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', - index=True, - readonly=True, - track_visibility='onchange', - ondelete='cascade') - - request_ids = fields.One2many( - 'opendons.request', - 'ensemble_id', - string='Request', - required=True, - track_visibility='onchange') - - request_count = fields.Integer( - compute='_compute_request_count', - string="# of request", - readonly=True - ) - csv_export = fields.Binary('csv export', filters='.csv', readonly=True) - document_fname=fields.Char() - - @api.depends('mailing_domain') - def _count_partner_ensemble(self): - for rec in self: - if rec.mailing_domain : - rec.partner_count=self.env['res.partner'].search_count(eval(rec.mailing_domain)) - else: - rec.partner_count=0 - - - def csv_export_ensemble(self): - - with open('export.csv', mode='w') as file: - writer = csv.writer(file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) - # create a row contains heading of each column - - writer.writerow(['name', 'email']) - # fetch products and write respective data. - partners = self.env['res.partner'].sudo().search([]) - - for p in partners: - name=p.name - email=p.email - writer.writerow([name,email]) - - with open('export.csv', '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='contacts.csv' - - return - - def _compute_request_count(self): - # The current user may not have access rights for donations - for ensemble in self: - try: - ensemble.request_count = len(ensemble.request_ids) - except Exception: - ensemble.request_count = 0 - - - - - def update_segment_domain(self,segment): - - logical_operator=segment.logical_operator - if logical_operator=='union': str_operator='"|",' - if logical_operator=='inter': str_operator='"&",' - - mailing_domain='' - - if len(segment.ensemble_ids)>1: - i=1 - for ens in segment.ensemble_ids: - - if i==1 and ens.mailing_domain!=False: - mailing_domain=ens.mailing_domain[1:-1] - if i>1 : - if ens.mailing_domain!=False: - mailing_domain=str_operator +mailing_domain+","+ens.mailing_domain[1:-1] - i+=1 - mailing_domain="["+mailing_domain+"]" - if len(segment.ensemble_ids)==1: - for ens in segment.ensemble_ids: - mailing_domain=ens.mailing_domain - - - - - return mailing_domain - - - @api.model - def create(self,vals): - - - res=super(opendons_ensemble, self).create(vals) - - segment=self.env['opendons.segment'].search([('id','=',int(res.segment_id))]) - #_logger.error('segment.id='+str(res.operation_id)) - segment_domain=self.update_segment_domain(segment) - - segment.write( - { - 'ensemble_count':len(segment.ensemble_ids), - 'mailing_domain':segment_domain, - }) - - operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) - __last_update=fields.Date.context_today(self) - operation.write({'__last_update':__last_update}) - - return res - - - - def write(self,vals): - - res=super(opendons_ensemble, self).write(vals) - mailing_domain=False - for val in vals: - if val=='logical_operator': - - mailing_domain=self.env['opendons.request'].update_ensemble_domain(self) - - if mailing_domain: - vals['mailing_domain']=mailing_domain - - segment=self.env['opendons.segment'].search([('id','=',int(self.segment_id))]) - segment_domain=self.update_segment_domain(segment) - segment.write({ - 'ensemble_count':len(segment.ensemble_ids), - 'mailing_domain':segment_domain - }) - segment=self.env['opendons.segment'].search([('id','=',int(self.segment_id))]) - operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) - __last_update=fields.Date.context_today(self) - operation.write({'__last_update':__last_update}) - - - res=super(opendons_ensemble, self).write(vals) - - def copy(self,default_values=None): - - vals={} - vals['name']='copy of ' + self.name - vals['segment_id']=int(self.segment_id) - vals['mailing_domain']=self.mailing_domain - dup_ensemble=super(opendons_ensemble, self).create(vals) - - #on duplique les requêtes de l'ensemble - for request_id in self.request_ids: - #raise Warning(segment_id.id) - req=self.env['opendons.request'].search([('id','=',int(request_id.id))]) - - if req: - vals3={} - vals3['ensemble_id']=dup_ensemble.id - vals3['name']=req.name - vals3['mailing_domain']=req.mailing_domain - #dup_segment=super(opendons_segment,self).create(vals2) - dup_request=self.env['opendons.request'].create(vals3) - dup_ensemble.write({'request_ids':[(4,dup_request.id)]}) - - - - #rtn=super(opendons_operation,self).copy(default=default_values) - - return dup_ensemble - -class opendons_request(models.Model): - _name = 'opendons.request' - _description = 'operation marketing request : a request is a part of contacts selected for an ensemble ' - _inherit = ['mail.thread'] - sequence = fields.Integer(string="sequence", default=10) - name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') - partner_count = fields.Integer(string="partners count", compute='_count_partner_request', readonly=True) - - partner_ids = fields.Many2many('res.partner', 'partner_request_rel', 'partner_id', 'request_id', string='partners') - - ensemble_id = fields.Many2one( - 'opendons.ensemble','Ensemble', - index=True, - readonly=True, - track_visibility='onchange', - ondelete='cascade') - - - mailing_domain = fields.Char( - string='Domain', - readonly=False, store=True) - - @api.depends('mailing_domain') - def _count_partner_request(self): - for rec in self: - if rec.mailing_domain : - rec.partner_count=self.env['res.partner'].search_count(eval(rec.mailing_domain)) - else: - rec.partner_count=0 - - def count_partners_ensemble(self,ensemble): - #on boucle sur toutes les requêtes de l'ensemble pour compter les contacts - result=0 - - for req in ensemble.request_ids: - result+=req.partner_count - - return result - - def update_ensemble_domain(self,ensemble): - #on boucle sur toutes les requêtes de l'ensemble - logical_operator=ensemble.logical_operator - if logical_operator=='union': str_operator='"|",' - if logical_operator=='inter': str_operator='"&",' - - mailing_domain='' - - if len(ensemble.request_ids)>1: - i=1 - for req in ensemble.request_ids: - - if i==1: mailing_domain=req.mailing_domain[1:-1] - - if i>1 : mailing_domain=str_operator +mailing_domain+","+req.mailing_domain[1:-1] - i+=1 - - mailing_domain="["+mailing_domain+"]" - - #si une seule requête pour l'ensemble - if len(ensemble.request_ids)==1: - for req in ensemble.request_ids: - mailing_domain=req.mailing_domain - - return mailing_domain - - def count_partners_segment(self,segment): - #on boucle sur toutes les requêtes de l'ensemble pour compter les contacts - result=0 - - for ensemble in segment.ensemble_ids: - result+=ensemble.partner_count - - return result - - def count_partners_operation(self,operation): - #on boucle sur toutes les requêtes de l'ensemble pour compter les contacts - result=0 - - for segment in operation.segment_ids: - result+=segment.partner_count - - return result - - - def refresh_partners_count(self): - - for r in self: - r.partner_count=self.env['res.partner'].search_count(eval(r.mailing_domain)) - - return True - - @api.model - def create(self,vals): - - #partners=self.count_partner_request(vals) - - if vals['mailing_domain']=="[]" : - vals['mailing_domain']="[[\"id\",\"!=\",False]]" - - res=super(opendons_request, self).create(vals) - - #mise à jour du nombre de requête pour l'ensemble,le segment et l'opération liée - ensemble=self.env['opendons.ensemble'].search([('id','=',int(res.ensemble_id))]) - - #partner_count=self.count_partners_ensemble(ensemble) - #mise à jour du domaine pour l'ensemble - ensemble_domain=self.update_ensemble_domain(ensemble) - - ensemble.write( - {'request_count':len(ensemble.request_ids), - 'mailing_domain':ensemble_domain - }) - - segment=self.env['opendons.segment'].search([('id','=',int(ensemble.segment_id))]) - segment_domain=ensemble.update_segment_domain(segment) - segment.write({ - 'mailing_domain':segment_domain - }) - - operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) - __last_update=fields.Date.context_today(self) - operation.write({'__last_update':__last_update}) - - - return res - - def write(self,vals): - - mailing_domain_update=False - for val in vals: - if val=='mailing_domain': - mailing_domain_update=True - - - if mailing_domain_update==True : - - if vals['mailing_domain']=="[]" : - vals['mailing_domain']="[[\"id\",\"!=\",False]]" - - - res=super(opendons_request, self).write(vals) - ensemble=self.env['opendons.ensemble'].search([('id','=',int(self.ensemble_id))]) - segment=self.env['opendons.segment'].search([('id','=',int(ensemble.segment_id))]) - if mailing_domain_update==True: - - ensemble_domain=self.update_ensemble_domain(ensemble) - # partner_count=self.count_partners_ensemble(ensemble) - ensemble.write({ - 'request_count':len(ensemble.request_ids), - 'mailing_domain':ensemble_domain - }) - - - segment_domain=ensemble.update_segment_domain(segment) - - segment.write({ - 'mailing_domain':segment_domain - }) - - operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) - __last_update=fields.Date.context_today(self) - operation.write({'__last_update':__last_update}) - - - return res - - def copy(self,default_values=None): - - vals={} - vals['name']='copy of ' + self.name - vals['ensemble_id']=int(self.ensemble_id) - vals['mailing_domain']=self.mailing_domain - dup_request=super(opendons_request, self).create(vals) - - - return dup_request - \ No newline at end of file diff --git a/models/operation_ensemble.py b/models/operation_ensemble.py new file mode 100644 index 0000000..6f60da7 --- /dev/null +++ b/models/operation_ensemble.py @@ -0,0 +1,200 @@ +from odoo import models, fields, api,_ +from odoo.exceptions import UserError, ValidationError,Warning +from psycopg2 import sql, DatabaseError + +from werkzeug import utils +import json +import logging +import xlwt +from io import BytesIO +import base64 +import csv +import os,secrets + +_logger = logging.getLogger(__name__) + +class opendons_ensemble(models.Model): + _name = 'opendons.ensemble' + _description = 'operation marketing ensemble : an ensemble is a part of contacts selected for an segment ' + _inherit = ['mail.thread'] + + name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') + logical_operator = fields.Selection([('union','union'),('inter','intersection')],'Type',default='union') + mailing_domain = fields.Char(string='partners selection') + 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', + index=True, + readonly=True, + track_visibility='onchange', + ondelete='cascade') + + request_ids = fields.One2many( + 'opendons.request', + 'ensemble_id', + string='Request', + required=True, + track_visibility='onchange') + + request_count = fields.Integer( + compute='_compute_request_count', + string="# of request", + readonly=True + ) + csv_export = fields.Binary('csv export', filters='.csv', readonly=True) + document_fname=fields.Char() + + @api.depends('mailing_domain') + def _count_partner_ensemble(self): + for rec in self: + if rec.mailing_domain : + rec.partner_count=self.env['res.partner'].search_count(eval(rec.mailing_domain)) + else: + rec.partner_count=0 + + + def csv_export_ensemble(self): + + with open('export.csv', mode='w') as file: + writer = csv.writer(file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) + # create a row contains heading of each column + + writer.writerow(['name', 'email']) + # fetch products and write respective data. + partners = self.env['res.partner'].sudo().search([]) + + for p in partners: + name=p.name + email=p.email + writer.writerow([name,email]) + + with open('export.csv', '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='contacts.csv' + + return + + def _compute_request_count(self): + # The current user may not have access rights for donations + for ensemble in self: + try: + ensemble.request_count = len(ensemble.request_ids) + except Exception: + ensemble.request_count = 0 + + + + + def update_segment_domain(self,segment): + + logical_operator=segment.logical_operator + if logical_operator=='union': str_operator='"|",' + if logical_operator=='inter': str_operator='"&",' + + mailing_domain='' + + if len(segment.ensemble_ids)>1: + i=1 + for ens in segment.ensemble_ids: + + if i==1 and ens.mailing_domain!=False: + mailing_domain=ens.mailing_domain[1:-1] + if i>1 : + if ens.mailing_domain!=False: + mailing_domain=str_operator +mailing_domain+","+ens.mailing_domain[1:-1] + i+=1 + mailing_domain="["+mailing_domain+"]" + if len(segment.ensemble_ids)==1: + for ens in segment.ensemble_ids: + mailing_domain=ens.mailing_domain + + + + + return mailing_domain + + + @api.model + def create(self,vals): + + + res=super(opendons_ensemble, self).create(vals) + + segment=self.env['opendons.segment'].search([('id','=',int(res.segment_id))]) + #_logger.error('segment.id='+str(res.operation_id)) + segment_domain=self.update_segment_domain(segment) + + segment.write( + { + 'ensemble_count':len(segment.ensemble_ids), + 'mailing_domain':segment_domain, + }) + + operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) + __last_update=fields.Date.context_today(self) + operation.write({'__last_update':__last_update}) + + return res + + + + def write(self,vals): + + res=super(opendons_ensemble, self).write(vals) + mailing_domain=False + for val in vals: + if val=='logical_operator': + + mailing_domain=self.env['opendons.request'].update_ensemble_domain(self) + + if mailing_domain: + vals['mailing_domain']=mailing_domain + + segment=self.env['opendons.segment'].search([('id','=',int(self.segment_id))]) + segment_domain=self.update_segment_domain(segment) + segment.write({ + 'ensemble_count':len(segment.ensemble_ids), + 'mailing_domain':segment_domain + }) + segment=self.env['opendons.segment'].search([('id','=',int(self.segment_id))]) + operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) + __last_update=fields.Date.context_today(self) + operation.write({'__last_update':__last_update}) + + + res=super(opendons_ensemble, self).write(vals) + + def copy(self,default_values=None): + + vals={} + vals['name']='copy of ' + self.name + vals['segment_id']=int(self.segment_id) + vals['mailing_domain']=self.mailing_domain + dup_ensemble=super(opendons_ensemble, self).create(vals) + + #on duplique les requêtes de l'ensemble + for request_id in self.request_ids: + #raise Warning(segment_id.id) + req=self.env['opendons.request'].search([('id','=',int(request_id.id))]) + + if req: + vals3={} + vals3['ensemble_id']=dup_ensemble.id + vals3['name']=req.name + vals3['mailing_domain']=req.mailing_domain + #dup_segment=super(opendons_segment,self).create(vals2) + dup_request=self.env['opendons.request'].create(vals3) + dup_ensemble.write({'request_ids':[(4,dup_request.id)]}) + + + + #rtn=super(opendons_operation,self).copy(default=default_values) + + return dup_ensemble \ No newline at end of file diff --git a/models/operation_request.py b/models/operation_request.py new file mode 100644 index 0000000..d699ff7 --- /dev/null +++ b/models/operation_request.py @@ -0,0 +1,191 @@ +from odoo import models, fields, api,_ +from odoo.exceptions import UserError, ValidationError,Warning +from psycopg2 import sql, DatabaseError + +from werkzeug import utils +import json +import logging +import xlwt +from io import BytesIO +import base64 +import csv +import os,secrets + +_logger = logging.getLogger(__name__) + +class opendons_request(models.Model): + _name = 'opendons.request' + _description = 'operation marketing request : a request is a part of contacts selected for an ensemble ' + _inherit = ['mail.thread'] + sequence = fields.Integer(string="sequence", default=10) + name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') + partner_count = fields.Integer(string="partners count", compute='_count_partner_request', readonly=True) + + partner_ids = fields.Many2many('res.partner', 'partner_request_rel', 'partner_id', 'request_id', string='partners') + + ensemble_id = fields.Many2one( + 'opendons.ensemble','Ensemble', + index=True, + readonly=True, + track_visibility='onchange', + ondelete='cascade') + + + mailing_domain = fields.Char( + string='Domain', + readonly=False, store=True) + + @api.depends('mailing_domain') + def _count_partner_request(self): + for rec in self: + if rec.mailing_domain : + rec.partner_count=self.env['res.partner'].search_count(eval(rec.mailing_domain)) + else: + rec.partner_count=0 + + def count_partners_ensemble(self,ensemble): + #on boucle sur toutes les requêtes de l'ensemble pour compter les contacts + result=0 + + for req in ensemble.request_ids: + result+=req.partner_count + + return result + + def update_ensemble_domain(self,ensemble): + #on boucle sur toutes les requêtes de l'ensemble + logical_operator=ensemble.logical_operator + if logical_operator=='union': str_operator='"|",' + if logical_operator=='inter': str_operator='"&",' + + mailing_domain='' + + if len(ensemble.request_ids)>1: + i=1 + for req in ensemble.request_ids: + + if i==1: mailing_domain=req.mailing_domain[1:-1] + + if i>1 : mailing_domain=str_operator +mailing_domain+","+req.mailing_domain[1:-1] + i+=1 + + mailing_domain="["+mailing_domain+"]" + + #si une seule requête pour l'ensemble + if len(ensemble.request_ids)==1: + for req in ensemble.request_ids: + mailing_domain=req.mailing_domain + + return mailing_domain + + def count_partners_segment(self,segment): + #on boucle sur toutes les requêtes de l'ensemble pour compter les contacts + result=0 + + for ensemble in segment.ensemble_ids: + result+=ensemble.partner_count + + return result + + def count_partners_operation(self,operation): + #on boucle sur toutes les requêtes de l'ensemble pour compter les contacts + result=0 + + for segment in operation.segment_ids: + result+=segment.partner_count + + return result + + + def refresh_partners_count(self): + + for r in self: + r.partner_count=self.env['res.partner'].search_count(eval(r.mailing_domain)) + + return True + + @api.model + def create(self,vals): + + #partners=self.count_partner_request(vals) + + if vals['mailing_domain']=="[]" : + vals['mailing_domain']="[[\"id\",\"!=\",False]]" + + res=super(opendons_request, self).create(vals) + + #mise à jour du nombre de requête pour l'ensemble,le segment et l'opération liée + ensemble=self.env['opendons.ensemble'].search([('id','=',int(res.ensemble_id))]) + + #partner_count=self.count_partners_ensemble(ensemble) + #mise à jour du domaine pour l'ensemble + ensemble_domain=self.update_ensemble_domain(ensemble) + + ensemble.write( + {'request_count':len(ensemble.request_ids), + 'mailing_domain':ensemble_domain + }) + + segment=self.env['opendons.segment'].search([('id','=',int(ensemble.segment_id))]) + segment_domain=ensemble.update_segment_domain(segment) + segment.write({ + 'mailing_domain':segment_domain + }) + + operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) + __last_update=fields.Date.context_today(self) + operation.write({'__last_update':__last_update}) + + + return res + + def write(self,vals): + + mailing_domain_update=False + for val in vals: + if val=='mailing_domain': + mailing_domain_update=True + + + if mailing_domain_update==True : + + if vals['mailing_domain']=="[]" : + vals['mailing_domain']="[[\"id\",\"!=\",False]]" + + + res=super(opendons_request, self).write(vals) + ensemble=self.env['opendons.ensemble'].search([('id','=',int(self.ensemble_id))]) + segment=self.env['opendons.segment'].search([('id','=',int(ensemble.segment_id))]) + if mailing_domain_update==True: + + ensemble_domain=self.update_ensemble_domain(ensemble) + # partner_count=self.count_partners_ensemble(ensemble) + ensemble.write({ + 'request_count':len(ensemble.request_ids), + 'mailing_domain':ensemble_domain + }) + + + segment_domain=ensemble.update_segment_domain(segment) + + segment.write({ + 'mailing_domain':segment_domain + }) + + operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))]) + __last_update=fields.Date.context_today(self) + operation.write({'__last_update':__last_update}) + + + return res + + def copy(self,default_values=None): + + vals={} + vals['name']='copy of ' + self.name + vals['ensemble_id']=int(self.ensemble_id) + vals['mailing_domain']=self.mailing_domain + dup_request=super(opendons_request, self).create(vals) + + + return dup_request \ No newline at end of file diff --git a/models/operation_segment.py b/models/operation_segment.py new file mode 100644 index 0000000..f58ccb8 --- /dev/null +++ b/models/operation_segment.py @@ -0,0 +1,171 @@ +from odoo import models, fields, api,_ +from odoo.exceptions import UserError, ValidationError,Warning +from psycopg2 import sql, DatabaseError + +from werkzeug import utils +import json +import logging +import xlwt +from io import BytesIO +import base64 +import csv +import os,secrets + +_logger = logging.getLogger(__name__) + + +class opendons_segment(models.Model): + _name = 'opendons.segment' + _description = 'operation marketing segment : a segment is a part of contacts selected for an operation ' + _inherit = ['mail.thread'] + sequence = fields.Integer(string="sequence", default=10) + #code=fields.Char(string='Code',required=True, translate=True,track_visibility='always') + name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') + exclusion=fields.Boolean(String='segment d\'exclusion',default=False,readonly=True) + logical_operator = fields.Selection([('union','union'),('inter','intersection')],'Type',default='union') + 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') + batch_export_id=fields.Many2one( + 'opendons.operation.batch_export', + String='batch export', + Domain="[('operation_id','=',operation_id)]", + track_visibility='onchange', + + ) + + @api.model + def _default_currency(self): + company = self.env['res.company']._company_default_get( + 'opendons.segment') + return company.currency_id + + currency_id = fields.Many2one( + 'res.currency', + string='Currency', + required=True, + track_visibility='onchange', + ondelete='restrict', + default=_default_currency + ) + + operation_id = fields.Many2one( + 'opendons.operation', + String='Operation', + index=True, + readonly=True, + track_visibility='onchange', + ondelete='cascade' + ) + + ensemble_ids = fields.One2many( + 'opendons.ensemble', + 'segment_id', + string='Ensemble', + required=True, + track_visibility='onchange') + + ensemble_count = fields.Integer( + compute='_compute_ensemble_count', + string="# of ensemble", + readonly=True + ) + chanel=fields.Selection([ + ('mail', 'Mailing'), + ('email', 'E-mailing'), + ('event', 'Event'), + ('face_to_face', 'Face to face')], + string='Chanel',required=True, translate=True,track_visibility='always') + + @api.depends('mailing_domain') + def _count_partner_segment(self): + for rec in self: + if rec.mailing_domain : + rec.partner_count=self.env['res.partner'].search_count(eval(rec.mailing_domain)) + else: + rec.partner_count=0 + + def _compute_ensemble_count(self): + # The current user may not have access rights for donations + for segment in self: + try: + segment.ensemble_count = len(segment.ensemble_ids) + except Exception: + segment.ensemble_count = 0 + + @api.model + def create(self,vals): + + + res=super(opendons_segment, self).create(vals) + #segment=self.env['opendons.segment'].search([('id','=',int(res.id))]) + operation=self.env['opendons.operation'].search([('id','=',int(res.operation_id))]) + #_logger.error('segment.id='+str(res.operation_id)) + __last_update=fields.Date.context_today(self) + operation.write( + { + 'segment_count':len(operation.segment_ids), + '__last_update':__last_update + } + ) + + return res + def write(self,vals): + + res=super(opendons_segment, self).write(vals) + mailing_domain=False + for val in vals: + if val=='logical_operator': + + mailing_domain=self.env['opendons.ensemble'].update_segment_domain(self) + + if mailing_domain: + vals['mailing_domain']=mailing_domain + + + + res=super(opendons_segment, self).write(vals) + + operation=self.env['opendons.operation'].search([('id','=',int(self.operation_id))]) + __last_update=fields.Date.context_today(self) + operation.write({'__last_update':__last_update}) + + def copy(self,default_values=None): + + vals={} + vals['name']='copy of ' + self.name + vals['operation_id']=int(self.operation_id) + vals['mailing_domain']=self.mailing_domain + dup_segment=super(opendons_segment, self).create(vals) + + #on duplique les ensembles du segment + for ensemble_id in self.ensemble_ids: + #raise Warning(segment_id.id) + ens=self.env['opendons.ensemble'].search([('id','=',int(ensemble_id.id))]) + + if ens: + vals3={} + vals3['segment_id']=dup_segment.id + vals3['name']=ens.name + vals3['mailing_domain']=ens.mailing_domain + #dup_segment=super(opendons_segment,self).create(vals2) + dup_ensemble=self.env['opendons.ensemble'].create(vals3) + dup_segment.write({'ensemble_ids':[(4,dup_ensemble.id)]}) + + for request_id in ens.request_ids: + req=self.env['opendons.request'].search([('id','=',int(request_id.id))]) + if req: + vals4={} + vals4['ensemble_id']=dup_ensemble.id + vals4['name']=req.name + vals4['mailing_domain']=req.mailing_domain + #dup_segment=super(opendons_segment,self).create(vals2) + dup_request=self.env['opendons.request'].create(vals4) + dup_ensemble.write({'request_ids':[(4,dup_request.id)]}) + + #rtn=super(opendons_operation,self).copy(default=default_values) + + return dup_segment \ No newline at end of file diff --git a/models/partner.py b/models/partner.py index 3e021cf..6c6726f 100644 --- a/models/partner.py +++ b/models/partner.py @@ -84,10 +84,10 @@ class partner(models.Model): ) - 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') + request_ids = fields.Many2many('opendons.request', 'request_partner_rel', 'partner_id', 'request_id', string='requests',ondelete='cascade') + operation_ids = fields.Many2many('opendons.operation', 'operation_partner_rel', 'partner_id', 'operation_id', string='operations',ondelete='cascade' ) + operation_excl_ids = fields.Many2many('opendons.operation', 'operation_excl_partner_rel', 'partner_id', 'operation_id', string='excluded operations',ondelete='cascade') + segment_ids = fields.Many2many('opendons.segment', 'segment_partner_rel', 'partner_id', 'segment_id', string='segments',ondelete='cascade') address_count = fields.Integer( diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 1a3d8e7..2453ccf 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -4,6 +4,7 @@ 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_batch_export,opendons.operation_batch_export,model_opendons_operation_batch_export,donation.group_donation_manager,1,1,1,1 access_opendons_segments,opendons.segments,model_opendons_segment,donation.group_donation_manager,1,1,1,1 diff --git a/views/operation.xml b/views/operation.xml index 3b5f4f5..eaa6548 100644 --- a/views/operation.xml +++ b/views/operation.xml @@ -30,7 +30,7 @@ - + @@ -39,6 +39,7 @@ --> + @@ -136,7 +137,7 @@ string="to Exported" states="validated"/>