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.
 
 

355 lines
13 KiB

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_operation(models.Model):
_name = 'opendons.operation'
_description = 'opération marketing : mailing, emailing evenements'
_inherit = ['mail.thread']
_check_company_auto = True
#_order = "__last_update desc"
code=fields.Char(string='Code',required=True, translate=True,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)
exported_date=fields.Date(string='Exported Date',track_visibility='always', readonly=True)
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(
"res.company",
string="Company",
required=True,
states={"exported": [("readonly", True)]},
default=lambda self: self.env.company
)
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'),
('event', 'Event'),
('face_to_face', 'Face to face')],
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')
quantity = fields.Integer(string="quantity",readonly=True)
@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
)
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'),
('validated', 'Validated'),
('exported', 'Exported')],
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()
batch_export_ids = fields.One2many(
'opendons.operation.batch_export',
'operation_id',
string='batchs export',
)
def validate(self):
for operation in self:
vals = {'state': 'validated'}
operation.write(vals)
return
def validated2draft(self):
'''from Done state to Cancel state'''
for operation in self:
operation.state = 'draft'
def validated2exported(self):
'''from Done state to Cancel state'''
for operation in self:
operation.state = 'exported'
def exported2validated(self):
'''from Done state to Cancel state'''
for operation in self:
operation.state = 'validated'
def csv_export_operation(self):
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)
if self.chanel=='email':
writer.writerow(['id','key','name','firstname','email','operation','segment'])
if self.chanel=='mail':
writer.writerow(['id','key','name','firstname','title','street','street2','city','cp','country_name','operation','segment'])
#sélections des contacts
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
firstname=p.firstname if p.firstname else ''
street=p.street if p.street else ''
street2=p.street2 if p.street2 else ''
city=p.city if p.city else ''
cp=p.zip if p.zip else ''
country_name=p.country_id.name if p.country_id else ''
title=p.title.name if p.title else ''
operation=int(self.id)
segment=int(seg.id)
if self.chanel=='email':
writer.writerow([id,key,name,firstname,email,operation,segment])
if self.chanel=='mail':
writer.writerow([id,key,name,firstname,title,street,street2,city,cp,country_name,operation,segment])
with open(csv_filename, 'r', encoding="utf-8") as f2:
data = str.encode(f2.read(), 'utf-8')
self.csv_export=base64.encodestring(data)
self.document_fname='operation'+str(self.id)+'.csv'
self.exported_date=fields.Date.context_today(self)
os.unlink(csv_filename)
return True
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')
i=1
for sg in segments:
if i==1:
mailing_domain='["&","!",'+segexcl.mailing_domain[1:-1]+','+ sg.mailing_domain[1:-1]+']'
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
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='["&","!",'+str_domain+ segexcl.mailing_domain[1:-1]+',' +sg.mailing_domain[1:-1]+']'
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
self.exported_date=fields.Date.context_today(self, readonly=True)
return True
@api.model
def create(self,vals):
op=self.env['opendons.operation'].search(['&',('name','=',vals['name']),('company_id','=',int(self.env.user.company_id))])
if "company_id" in vals:
self = self.with_company(vals["company_id"])
if op : raise Warning(_('name already exist'))
res=super(opendons_operation, self).create(vals)
#création du segment d'exclusion
vals2={}
vals2['operation_id']=res.id
vals2['sequence']=1
vals2['name']='Exclusion'
vals2['exclusion']=True
res2=self.env['opendons.segment'].create(vals2)
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()
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
def copy(self,default_values=None):
vals={}
vals['name']='copy of ' + self.name
vals['chanel']=self.chanel
vals['user_id']=self._uid
vals['state']='draft'
dup_operation=super(opendons_operation, self).create(vals)
#on duplique les segment de l'opération
for segment_id in self.segment_ids:
#raise Warning(segment_id.id)
seg=self.env['opendons.segment'].search([('id','=',int(segment_id.id))])
if seg:
vals2={}
vals2['operation_id']=dup_operation.id
vals2['name']=seg.name
vals2['mailing_domain']=seg.mailing_domain
#dup_segment=super(opendons_segment,self).create(vals2)
dup_segment=self.env['opendons.segment'].create(vals2)
dup_operation.write({'segment_ids':[(4,dup_segment.id)]})
for ensemble_id in seg.ensemble_ids:
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_operation