Browse Source

operations

master
root 3 years ago
parent
commit
c711c89ade
8 changed files with 602 additions and 529 deletions
  1. +3
    -0
      models/__init__.py
  2. +20
    -522
      models/operation.py
  3. +200
    -0
      models/operation_ensemble.py
  4. +191
    -0
      models/operation_request.py
  5. +171
    -0
      models/operation_segment.py
  6. +4
    -4
      models/partner.py
  7. +1
    -0
      security/ir.model.access.csv
  8. +12
    -3
      views/operation.xml

+ 3
- 0
models/__init__.py View File

@ -7,6 +7,9 @@ from . import address
from . import email from . import email
from . import phone from . import phone
from . import operation from . import operation
from . import operation_segment
from . import operation_ensemble
from . import operation_request
from . import relationship from . import relationship
from . import returnmail from . import returnmail
from . import payment_batch from . import payment_batch


+ 20
- 522
models/operation.py View File

@ -13,16 +13,6 @@ import os,secrets
_logger = logging.getLogger(__name__) _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): class opendons_operation(models.Model):
_name = 'opendons.operation' _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') name=fields.Char(string='Name',required=True, translate=True,copy=False,default='campagne',track_visibility='always')
partner_count = fields.Integer(string="count",readonly=True) partner_count = fields.Integer(string="count",readonly=True)
exported_date=fields.Date(string='Exported Date',track_visibility='always', 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') partner_ids = fields.Many2many('res.partner', 'partner_operation_rel', 'partner_id', 'operation_id', string='partners')
#contacts exclus de l'opération #contacts exclus de l'opération
company_id = fields.Many2one( company_id = fields.Many2one(
@ -58,6 +47,7 @@ class opendons_operation(models.Model):
cost = fields.Monetary( cost = fields.Monetary(
string='Cost', string='Cost',
currency_field='currency_id') currency_field='currency_id')
quantity = fields.Integer(string="quantity",readonly=True)
@api.model @api.model
def _default_currency(self): def _default_currency(self):
@ -107,6 +97,13 @@ class opendons_operation(models.Model):
csv_export = fields.Binary('csv export', filters='.csv', readonly=True) csv_export = fields.Binary('csv export', filters='.csv', readonly=True)
document_fname=fields.Char() document_fname=fields.Char()
batch_export_ids = fields.One2many(
'opendons.operation.batch_export',
'operation_id',
string='batchs export',
)
def validate(self): def validate(self):
@ -199,9 +196,6 @@ class opendons_operation(models.Model):
segexcl=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=',True)]) 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') segments=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=',False)],order='sequence asc')
i=1 i=1
@ -239,9 +233,9 @@ class opendons_operation(models.Model):
else: else:
str_domain='' 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]+']' 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)) partners=self.env['res.partner'].search(eval(mailing_domain))
#ajouts des contact à l'opération #ajouts des contact à l'opération
self.partner_ids=partners self.partner_ids=partners
@ -279,7 +273,11 @@ class opendons_operation(models.Model):
return res 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) #rtn=super(opendons_operation,self).copy(default=default_values)
return dup_operation 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( operation_id = fields.Many2one(
'opendons.operation', 'opendons.operation',
String='Operation', String='Operation',
@ -395,478 +366,5 @@ class opendons_segment(models.Model):
track_visibility='onchange', track_visibility='onchange',
ondelete='cascade' 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

+ 200
- 0
models/operation_ensemble.py View File

@ -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

+ 191
- 0
models/operation_request.py View File

@ -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

+ 171
- 0
models/operation_segment.py View File

@ -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

+ 4
- 4
models/partner.py View File

@ -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( address_count = fields.Integer(


+ 1
- 0
security/ir.model.access.csv View File

@ -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_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_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_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 access_opendons_segments,opendons.segments,model_opendons_segment,donation.group_donation_manager,1,1,1,1


+ 12
- 3
views/operation.xml View File

@ -30,7 +30,7 @@
<tree duplicate="1"> <tree duplicate="1">
<field name="id"/> <field name="id"/>
<field name="company_id"/>
<!-- <field name="company_id"/> -->
<field name="__last_update"/> <field name="__last_update"/>
<field name="name"/> <field name="name"/>
<field name="chanel"/> <field name="chanel"/>
@ -39,6 +39,7 @@
<field name="end_date"/> --> <field name="end_date"/> -->
<field name="user_id"/> <field name="user_id"/>
<field name="cost"/> <field name="cost"/>
<field name="state" invisible="context.get('recurring_view')"/> <field name="state" invisible="context.get('recurring_view')"/>
</tree> </tree>
</field> </field>
@ -136,7 +137,7 @@
string="to Exported" states="validated"/> string="to Exported" states="validated"/>
<button type="object" name="exported2validated" <button type="object" name="exported2validated"
string="Back to Validated" states="exported"/> string="Back to Validated" states="exported"/>
<button type="object" name="csv_export_operation" string="Generate csv export"
<button type="object" name="csv_export_operation" string="Generate csv export"
states="draft" /> states="draft" />
<field name="state" widget="statusbar" <field name="state" widget="statusbar"
invisible="context.get('recurring_view')" invisible="context.get('recurring_view')"
@ -151,8 +152,15 @@
<field name="code"/> <field name="code"/>
<field name="chanel"/> <field name="chanel"/>
<field name="cost"/> <field name="cost"/>
<field name="quantity"/>
<field name="batch_export_ids">
<tree editable="bottom">
<field name="name"/>
</tree>
</field>
<!-- <button type="object" name="validate" string="global scheme" class="oe_highlight"/> --> <!-- <button type="object" name="validate" string="global scheme" class="oe_highlight"/> -->
<field name="csv_export" filename="document_fname" widget="binary"/>
<field name="csv_export" filename="document_fname" widget="binary"/>
<field name="document_fname" invisible="1"/> <field name="document_fname" invisible="1"/>
<field name="exported_date">%b-%d-%Y</field> <field name="exported_date">%b-%d-%Y</field>
@ -186,6 +194,7 @@
<field name="id"/> <field name="id"/>
<field name="name"/> <field name="name"/>
<field name="chanel"/> <field name="chanel"/>
<field name="batch_export_id"/>
<field name="logical_operator"/> <field name="logical_operator"/>
<field name="mailing_domain" widget="domain" options="{'model': 'res.partner', 'in_dialog': true}"/> <field name="mailing_domain" widget="domain" options="{'model': 'res.partner', 'in_dialog': true}"/>


Loading…
Cancel
Save