You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

516 lines
16 KiB

from odoo import models, fields, api
from odoo.exceptions import UserError, ValidationError
from psycopg2 import sql, DatabaseError
from werkzeug import utils
import json
import logging
import xlwt
from io import BytesIO
import base64
import csv
_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'
_description = 'opération marketing : mailing, emailing evenements'
_inherit = ['mail.thread']
code=fields.Char(string='Code',required=True, translate=True,track_visibility='always')
name=fields.Char(string='Name',required=True, translate=True,track_visibility='always')
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')
chanel=fields.Selection([
('mail', 'Mailing'),
('email', 'E-mailing'),
('event', 'Event')],
string='Chanel',required=True, translate=True,track_visibility='always')
user_id = fields.Many2one('res.users', string='Author', default=lambda self: self.env.uid)
cost = fields.Monetary(
string='Cost',
currency_field='currency_id')
@api.model
def _default_currency(self):
company = self.env['res.company']._company_default_get(
'opendons.operation')
return company.currency_id
currency_id = fields.Many2one(
'res.currency',
string='Currency',
required=True,
track_visibility='onchange',
ondelete='restrict',
default=_default_currency
)
_sql_constraints = [
('name_uniq', 'unique (name)', "Name already exists !"),
('code_uniq', 'unique (code)', "Code already exists !"),
]
number_of_sending = fields.Integer(
compute='_compute_number_of_sending',
string="# of sending",
readonly=True
)
segment_ids = fields.One2many(
'opendons.segment',
'operation_id',
string='Segments',
readonly=True
)
segment_count = fields.Integer(
string="# of segment",
readonly=True
)
state = fields.Selection([
('draft', 'Draft'),
('done', 'Done'),
('cancel', 'Cancelled')],
string='State',
readonly=True,
copy=False,
default='draft',
index=True,
track_visibility='onchange'
)
csv_export = fields.Binary('csv export', filters='.csv', readonly=True)
document_fname=fields.Char()
# def _compute_segment_count(self):
# # The current user may not have access rights for donations
# for operation in self:
# try:
# operation.segment_count = len(operation.segment_ids)
# except Exception:
# operation.segment_count = 0
def validate(self):
for operation in self:
vals = {'state': 'done'}
operation.write(vals)
return
def done2cancel(self):
'''from Done state to Cancel state'''
for operation in self:
operation.state = 'cancel'
def cancel2draft(self):
'''from Cancel state to Draft state'''
for operation in self:
operation.state = 'draft'
def csv_export_operation(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='operation'+str(self.id)+'.csv'
return
def export_partners(self):
partners = self.env['res.partner'].sudo().search([])
stream = BytesIO()
book = xlwt.Workbook(encoding='utf-8')
sheet = book.add_sheet(u'{}'.format(u'My Sheet'))
row = 1
cell = 0
for p in partners:
sheet.write(row, cell, p.name)
row += 1
book.save(stream)
self.excel_report = base64.encodestring(stream.getvalue())
self.document_fname='operation'+seld.id+'.csv'
return
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)
logical_operator = fields.Selection([('union','union'),('inter','intersection')],'Type',default='union')
cost = fields.Monetary(
string='Cost',
currency_field='currency_id')
partner_count = fields.Integer(string="count",readonly=True)
@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='restrict'
)
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
)
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))
operation.write({'segment_count':len(operation.segment_ids)})
return res
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',
readonly=True, store=True)
partner_count = fields.Integer(string="count",readonly=True)
sequence = fields.Integer(string="sequence", default=10)
segment_id = fields.Many2one(
'opendons.segment','Segment',
index=True,
readonly=True,
track_visibility='onchange',
ondelete='restrict')
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()
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
@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.write({'ensemble_count':len(segment.ensemble_ids)})
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_domaine(self)
if mailing_domain: vals['mailing_domain']=mailing_domain
res=super(opendons_ensemble, self).write(vals)
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="count",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='restrict')
mailing_domain = fields.Char(
string='Domain',
readonly=False, store=True)
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_domaine(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+"]"
if len(ensemble.request_ids)==1:
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 count_partner_request(self,vals):
if vals['mailing_domain']:
partners=self.env['res.partner'].search(eval(vals['mailing_domain']))
else:
partners=self.env['res.partner']
result=len(partners)
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)
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_domaine=self.update_ensemble_domaine(ensemble)
ensemble.write(
{'request_count':len(ensemble.request_ids),
'mailing_domain':ensemble_domaine
})
# segment=self.env['opendons.segment'].search([('id','=',int(ensemble.segment_id))])
# partner_count=self.count_partners_segment(segment)
# segment.write({
# 'partner_count':partner_count
# })
# operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))])
# partner_count=self.count_partners_operation(operation)
# operation.write({
# 'partner_count':partner_count
# })
return res
def write(self,vals):
mailing_domain_update=False
for val in vals:
if val=='mailing_domain':
mailing_domain_update=True
partners_count=self.count_partner_request(vals)
#partner_count=len(partners)
#partner_ids=[(6, 0,partners.ids)]
if mailing_domain_update==True :
vals['partner_count']=partners_count
res=super(opendons_request, self).write(vals)
if mailing_domain_update==True:
# #mise à jour du nombre de requête pour l'ensemble lié
ensemble=self.env['opendons.ensemble'].search([('id','=',int(self.ensemble_id))])
ensemble_domaine=self.update_ensemble_domaine(ensemble)
# partner_count=self.count_partners_ensemble(ensemble)
ensemble.write({
'request_count':len(ensemble.request_ids),
'mailing_domain':ensemble_domaine
})
# segment=self.env['opendons.segment'].search([('id','=',int(ensemble.segment_id))])
# partner_count=self.count_partners_segment(segment)
# segment.write({
# 'partner_count':partner_count
# })
# operation=self.env['opendons.operation'].search([('id','=',int(segment.operation_id))])
# partner_count=self.count_partners_operation(operation)
# operation.write({
# 'partner_count':partner_count
# })
return res