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.
 
 

372 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
from datetime import datetime,timedelta,date
_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 asc"
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
res=self.select_partner_operation()
segments=self.env['opendons.segment'].search(['&',('operation_id','=',self.id),('exclusion','=',False)])
#extraction des contacts sélectionnés sur chaque segment
q=0
for seg in segments:
if seg.partner_ids:
for p in seg.partner_ids:
#raise UserError(p)
id=p.id
key=p.key
name=p.name
email=p.email
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])
q=q+1
with open(csv_filename, 'r', encoding="utf-8") as f2:
data = str.encode(f2.read(), 'utf-8')
self.quantity=q
self.csv_export=base64.encodestring(data)
self.document_fname='operation'+str(self.id)+'.csv'
self.exported_date=fields.Date.context_today(self)
#generation des exports par lot
for batch_export_id in self.batch_export_ids:
batch_export_id.csv_export_batch()
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:
if segexcl.mailing_domain:
mailing_domain='["&","!",'+segexcl.mailing_domain[1:-1]+','+ sg.mailing_domain[1:-1]+']'
else:
mailing_domain='['+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=''
if segexcl.mailing_domain:
mailing_domain='["&","!",'+str_domain+ segexcl.mailing_domain[1:-1]+',' +sg.mailing_domain[1:-1]+']'
else:
mailing_domain='["&",'+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=datetime.now()
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