diff --git a/__manifest__.py b/__manifest__.py index cbf6cd1..e650093 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- { - 'name': "opendons_module1", + 'name': "opendons", 'summary': """ Short (1 phrase/line) summary of the module's purpose, used as @@ -20,16 +20,20 @@ 'version': '0.1', # any module necessary for this one to work correctly - 'depends': ['base','mail'], + 'depends': ['base','mail','mass_mailing'], # always loaded 'data': [ 'security/ir.model.access.csv', 'views/qualifier.xml', 'views/address.xml', + 'views/email.xml', + 'views/phone.xml', 'views/partner.xml', + 'views/relationship.xml', 'views/operation.xml', - 'views/templates.xml' + 'views/templates.xml', + 'views/mail_mail.xml' ], # only loaded in demonstration mode diff --git a/models/__init__.py b/models/__init__.py index 7de966d..b3d10fa 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -3,4 +3,8 @@ from . import qualifier from . import partner from . import address -from . import operation \ No newline at end of file +from . import email +from . import phone +from . import operation +from . import mailing_mailing +from . import relationship \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-37.pyc b/models/__pycache__/__init__.cpython-37.pyc index 09e4a8f..1b88137 100644 Binary files a/models/__pycache__/__init__.cpython-37.pyc and b/models/__pycache__/__init__.cpython-37.pyc differ diff --git a/models/__pycache__/address.cpython-37.pyc b/models/__pycache__/address.cpython-37.pyc index 709d419..52c6833 100644 Binary files a/models/__pycache__/address.cpython-37.pyc and b/models/__pycache__/address.cpython-37.pyc differ diff --git a/models/__pycache__/email.cpython-37.pyc b/models/__pycache__/email.cpython-37.pyc new file mode 100644 index 0000000..c0b93ab Binary files /dev/null and b/models/__pycache__/email.cpython-37.pyc differ diff --git a/models/__pycache__/mail_mail.cpython-37.pyc b/models/__pycache__/mail_mail.cpython-37.pyc new file mode 100644 index 0000000..2ae2398 Binary files /dev/null and b/models/__pycache__/mail_mail.cpython-37.pyc differ diff --git a/models/__pycache__/mailing_mailing.cpython-37.pyc b/models/__pycache__/mailing_mailing.cpython-37.pyc new file mode 100644 index 0000000..761d595 Binary files /dev/null and b/models/__pycache__/mailing_mailing.cpython-37.pyc differ diff --git a/models/__pycache__/operation.cpython-37.pyc b/models/__pycache__/operation.cpython-37.pyc index 55cd511..855e842 100644 Binary files a/models/__pycache__/operation.cpython-37.pyc and b/models/__pycache__/operation.cpython-37.pyc differ diff --git a/models/__pycache__/partner.cpython-37.pyc b/models/__pycache__/partner.cpython-37.pyc index 83f4c33..40e5904 100644 Binary files a/models/__pycache__/partner.cpython-37.pyc and b/models/__pycache__/partner.cpython-37.pyc differ diff --git a/models/__pycache__/phone.cpython-37.pyc b/models/__pycache__/phone.cpython-37.pyc new file mode 100644 index 0000000..9b4f07a Binary files /dev/null and b/models/__pycache__/phone.cpython-37.pyc differ diff --git a/models/__pycache__/qualifier.cpython-37.pyc b/models/__pycache__/qualifier.cpython-37.pyc index 7188970..8720a4f 100644 Binary files a/models/__pycache__/qualifier.cpython-37.pyc and b/models/__pycache__/qualifier.cpython-37.pyc differ diff --git a/models/__pycache__/relationship.cpython-37.pyc b/models/__pycache__/relationship.cpython-37.pyc new file mode 100644 index 0000000..5b1d92a Binary files /dev/null and b/models/__pycache__/relationship.cpython-37.pyc differ diff --git a/models/address.py b/models/address.py index 0c807a0..1f384bd 100644 --- a/models/address.py +++ b/models/address.py @@ -46,16 +46,18 @@ class opendons_partneraddress(models.Model): ) def write(self,vals): - + date_active=False + date_inactive=False for val in vals: if val=='active' and not vals['active']: date_inactive=fields.Date.context_today(self) if val=='active' and vals['active']: - date_inactive=False + date_inactive=False + date_active=fields.Date.context_today(self) + - vals['npai']=0 vals['date_inactive']=date_inactive - #self.message_post(body=_('remise à zero du compteur NPAI')) + vals['date_active']=date_active res = super(opendons_partneraddress, self).write(vals) diff --git a/models/email.py b/models/email.py new file mode 100644 index 0000000..bf4c558 --- /dev/null +++ b/models/email.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api +from odoo.exceptions import UserError, ValidationError +from psycopg2 import sql, DatabaseError +from odoo.tools.safe_eval import safe_eval, datetime + +from werkzeug import utils + + + +class opendons_partneremail(models.Model): + _name = 'opendons.partneremail' + _description = 'emails du contact' + _inherit = ['mail.thread'] + + email = fields.Char() + + active=fields.Boolean(string='active',default=True,track_visibility='always') + date_active=fields.Date(readonly=True,string='Date active',track_visibility='always') + date_inactive=fields.Date(readonly=True,string='Date inactive',track_visibility='always') + + partner_id = fields.Many2one( + 'res.partner', + string='partner', + required=True, + index=True, + readonly=True, + track_visibility='onchange', + ondelete='restrict' + ) + + def write(self,vals): + date_active=False + date_inactive=False + for val in vals: + if val=='active' and not vals['active']: + date_inactive=fields.Date.context_today(self) + if val=='active' and vals['active']: + date_inactive=False + date_active=fields.Date.context_today(self) + + + vals['date_inactive']=date_inactive + vals['date_active']=date_active + + + res = super(opendons_partneremail, self).write(vals) + + #Your code goes here + return res + + + + + diff --git a/models/mailing_mailing.py b/models/mailing_mailing.py new file mode 100644 index 0000000..b46c24f --- /dev/null +++ b/models/mailing_mailing.py @@ -0,0 +1,16 @@ +import re +import werkzeug.urls + +from odoo import api, fields, models, tools + + +class Mailing(models.Model): + _inherit = 'mailing.mailing' + operation_id=fields.Many2one('opendons.operation','Operation') + segment_id=fields.Many2one('opendons.segment','Segment') + + @api.onchange('operation_id') + def _onchange_operation_id(self): + res = {} + res['domain']={'segment_id':[('operation_id', '=', self.operation_id.id)]} + return res \ No newline at end of file diff --git a/models/operation.py b/models/operation.py index 5bae2e1..5fec2e2 100644 --- a/models/operation.py +++ b/models/operation.py @@ -3,6 +3,25 @@ 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' @@ -11,8 +30,10 @@ class opendons_operation(models.Model): code=fields.Char(string='Code',required=True, translate=True,track_visibility='always') name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') - 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') + 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'), @@ -52,19 +73,115 @@ class opendons_operation(models.Model): 'opendons.segment', 'operation_id', string='Segments', - required=True, - track_visibility='onchange') + 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): @@ -82,8 +199,318 @@ class opendons_segment(models.Model): ) operation_id = fields.Many2one( - 'opendons.operation','Operation', - ondelete='cascade', - track_visibility='always') + '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 + \ No newline at end of file diff --git a/models/partner.py b/models/partner.py index 9407dc7..25ad49c 100644 --- a/models/partner.py +++ b/models/partner.py @@ -29,6 +29,30 @@ class partner(models.Model): partner.address_count = len(partner.address_ids) except Exception: partner.address_count = 0 + + def _compute_email_count(self): + # The current user may not have access rights for donations + for partner in self: + try: + partner.email_count = len(partner.email_ids) + except Exception: + partner.email_count = 0 + + def _compute_phone_count(self): + # The current user may not have access rights for donations + for partner in self: + try: + partner.phone_count = len(partner.phone_ids) + except Exception: + partner.phone_count = 0 + + def _compute_relationshipPartner_count(self): + # The current user may not have access rights for donations + for partner in self: + try: + partner.relationshipPartner_count = len(partner.relationshipPartner_ids) + except Exception: + partner.relationshipPartner_count = 0 qualifier_ids = fields.One2many( 'opendons_qualifier.partnerqualifier', @@ -48,9 +72,51 @@ class partner(models.Model): string='Address', readonly=True ) + + # request_ids = fields.One2many( + # 'opendons.request', + # 'partner_ids', + # string='Request', + # readonly=True + # ) + request_ids = fields.Many2many('opendons.request', 'request_partner_rel', 'partner_id', 'request_id', string='requests') + address_count = fields.Integer( compute='_compute_address_count', string="# of Addresses", readonly=True ) + relationshipPartner_ids = fields.One2many( + 'opendons_relationship.partner', + 'partner_id', + string='Relationship', + readonly=True + ) + relationshipPartner_count = fields.Integer( + compute='_compute_relationshipPartner_count', + string="# of Relationship", + readonly=True + ) + email_ids = fields.One2many( + 'opendons.partneremail', + 'partner_id', + string='Email', + readonly=True + ) + email_count = fields.Integer( + compute='_compute_email_count', + string="# of email", + readonly=True + ) + phone_ids = fields.One2many( + 'opendons.partnerphone', + 'partner_id', + string='Phone', + readonly=True + ) + phone_count = fields.Integer( + compute='_compute_phone_count', + string="# of phone", + readonly=True + ) diff --git a/models/phone.py b/models/phone.py new file mode 100644 index 0000000..1de95ee --- /dev/null +++ b/models/phone.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api +from odoo.exceptions import UserError, ValidationError +from psycopg2 import sql, DatabaseError +from odoo.tools.safe_eval import safe_eval, datetime + +from werkzeug import utils + + + +class opendons_partnerphone(models.Model): + _name = 'opendons.partnerphone' + _description = 'telephones du contact' + _inherit = ['mail.thread'] + + phone = fields.Char() + + active=fields.Boolean(string='active',default=True,track_visibility='always') + date_active=fields.Date(readonly=True,string='Date active',track_visibility='always') + date_inactive=fields.Date(readonly=True,string='Date inactive',track_visibility='always') + + partner_id = fields.Many2one( + 'res.partner', + string='partner', + required=True, + index=True, + readonly=True, + track_visibility='onchange', + ondelete='restrict' + ) + + def write(self,vals): + date_active=False + date_inactive=False + for val in vals: + if val=='active' and not vals['active']: + date_inactive=fields.Date.context_today(self) + if val=='active' and vals['active']: + date_inactive=False + date_active=fields.Date.context_today(self) + + + vals['date_inactive']=date_inactive + vals['date_active']=date_active + + + res = super(opendons_partnerphone, self).write(vals) + + #Your code goes here + return res + + + + + diff --git a/models/qualifier.py b/models/qualifier.py index 962ed4c..0a58a62 100644 --- a/models/qualifier.py +++ b/models/qualifier.py @@ -33,19 +33,37 @@ class opendons_qualifier(models.Model): _description = 'qualificatifs de contacts' name = fields.Char() - type=fields.Selection([('checkbox','checkbox'),('text','text'),('numerical','numerical')], default='checkbox') + #type=fields.Selection([('checkbox','checkbox'),('text','text'),('numerical','numerical')], default='checkbox') default_value = fields.Char() description = fields.Text() category_id = fields.Many2one( 'opendons_qualifier.category', string='Category', tracking=True, required=True) + @api.model + def create(self,vals): + + + + res = super(opendons_qualifier, self).create(vals) + + #ajout du qualificatif nouvellement créé pour chaque contact + for partner in self.env['res.partner'].sudo().search([]): + + + create_partner_qualifier=self.env['opendons_qualifier.partnerqualifier'].sudo().create( + {'partner_id': int(partner.id), + 'qualifier_id':int(res.id)}) + + + return res + class opendons_partnerqualifier(models.Model): _name = 'opendons_qualifier.partnerqualifier' _description = 'qualificatifs pour stocker les valeurs au niveau du contact' - + actif=fields.Boolean(string='actif',default=False) value=fields.Char() qualifier_id=fields.Many2one('opendons_qualifier.qualifier',string='qualifier') category = fields.Char(related='qualifier_id.category_id.name') diff --git a/models/relationship.py b/models/relationship.py new file mode 100644 index 0000000..74bd649 --- /dev/null +++ b/models/relationship.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api +from odoo.exceptions import UserError, ValidationError +from psycopg2 import sql, DatabaseError + +from werkzeug import utils + +class opendons_relationshipType(models.Model): + _name = 'opendons_relationship.type' + _description = 'type de la relation' + + name = fields.Char('Name', required=True) + description = fields.Text() + + nature_ids = fields.One2many( + 'opendons_relationship.nature', + 'type_id', + string='Nature', + required=True, + track_visibility='onchange') + + @api.constrains('name') + def _check_name(self): + + count=self.search_count([('name','=',self.name),('id', '!=', self.id)]) + if count>0: + raise UserError('This name already exist') + +class opendons_relationshipNature(models.Model): + _name = 'opendons_relationship.nature' + _description = 'nature de la relation' + + name = fields.Char('Name', required=True) + description = fields.Text() + type_id = fields.Many2one( + 'opendons_relationship.type', string='Type', tracking=True, + required=True) + + + @api.constrains('name') + def _check_name(self): + + count=self.search_count([('name','=',self.name),('id', '!=', self.id)]) + if count>0: + raise UserError('This name already exist') + +class opendons_relationshipPartner(models.Model): + _name = 'opendons_relationship.partner' + _description = 'relations pour un contact' + + type_id=fields.Many2one('opendons_relationship.type',string='type') + nature_id=fields.Many2one('opendons_relationship.nature',string='nature') + + #nature = fields.Char(related='type_id.nature_id.name') + partner_id = fields.Many2one( + 'res.partner', + string='partner', + required=True, + index=True, + readonly=True, + track_visibility='onchange', + ondelete='restrict' + ) + partnerRelationship_id = fields.Many2one( + 'res.partner', + string='partner relationship', + required=True, + index=True, + track_visibility='onchange', + ondelete='restrict' + ) + active=fields.Boolean(string='active',default=True,track_visibility='always') + #date_active=fields.Date(readonly=True,default=lambda self: fields.Date.today(),string='Date active',track_visibility='always') + date_active=fields.Date(readonly=True,string='Date active',track_visibility='always') + date_inactive=fields.Date(readonly=True,string='Date inactive',track_visibility='always') + + @api.onchange('type_id') + def _onchange_type_id(self): + res = {} + res['domain']={'nature_id':[('type_id', '=', self.type_id.id)]} + return res + + + # def create(self,vals): + + + # # vals['active']=fields.Date.context_today(self) + # res = super(opendons_relationshipPartner, self).create(vals) + + # return res + + def write(self,vals): + date_active=False + date_inactive=False + for val in vals: + if val=='active' and not vals['active']: + date_inactive=fields.Date.context_today(self) + if val=='active' and vals['active']: + date_inactive=False + date_active=fields.Date.context_today(self) + + + vals['date_inactive']=date_inactive + vals['date_active']=date_active + + + res = super(opendons_relationshipPartner, self).write(vals) + + + return res + + @api.model + def create(self,vals): + + vals['date_active']=fields.Date.context_today(self) + res = super(opendons_relationshipPartner, self).create(vals) + + #Attention la relation est reciproque entre les 2 contacts,donc on doit créer la relation pour l'autre contact + vals2={} + vals2['type_id']=int(res.type_id) + vals2['nature_id']=int(res.nature_id) + vals2['partner_id']=int(res.partnerRelationship_id) + vals2['partnerRelationship_id']=int(res.partner_id) + vals2['active']=True + vals2['date_active']=fields.Date.context_today(self) + + + res2=super(opendons_relationshipPartner, self).create(vals2) + + + + return res + + + # sql_constraints = [ + # ('qualifier_uniq', 'unique (qualifier_id,partner_id)', 'A qualifier could be defined only one time on same partner.') + # ] + + # @api.constrains('qualifier_id') + # def _check_qualifier_id(self): + # for q in self: + # result=self.search_count([('qualifier_id','=',int(self.qualifier_id)),('id', '!=', self.id),('partner_id','=',int(self.partner_id))]) + # if result>0: + # raise UserError('A qualifier could be defined only one time on same partner.') \ No newline at end of file diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 2dd4f97..05db5c6 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -3,4 +3,13 @@ access_opendons_qualifier_qualifier,opendons_qualifier.qualifier,model_opendons_ access_opendons_qualifier_category,opendons_qualifier.category,model_opendons_qualifier_category,donation_main.group_donation_manager,1,1,1,1 access_opendons_qualifier_partnerqualifier,opendons_qualifier.partnerqualifier,model_opendons_qualifier_partnerqualifier,donation_main.group_donation_manager,1,1,1,1 access_opendons_partneraddress,opendons.partneraddress,model_opendons_partneraddress,donation_main.group_donation_manager,1,1,1,1 -access_opendons_operations,opendons.operations,model_opendons_operation,donation_main.group_donation_manager,1,1,1,1 \ No newline at end of file +access_opendons_operations,opendons.operations,model_opendons_operation,donation_main.group_donation_manager,1,1,1,1 +access_opendons_segments,opendons.segments,model_opendons_segment,donation_main.group_donation_manager,1,1,1,1 +access_opendons_ensembles,opendons.ensembles,model_opendons_ensemble,donation_main.group_donation_manager,1,1,1,1 +access_opendons_requests,opendons.requests,model_opendons_request,donation_main.group_donation_manager,1,1,1,1 + +access_opendons_relationship_partner,opendons_relationship.partner,model_opendons_relationship_partner,donation_main.group_donation_manager,1,1,1,1 +access_opendons_relationship_nature,opendons_relationship.nature,model_opendons_relationship_nature,donation_main.group_donation_manager,1,1,1,1 +access_opendons_relationship_type,opendons_relationship.type,model_opendons_relationship_type,donation_main.group_donation_manager,1,1,1,1 +access_opendons_partneremail,opendons_partneremail,model_opendons_partneremail,donation_main.group_donation_manager,1,1,1,1 +ccess_opendons_partnerphone,opendons_partnerphone,model_opendons_partnerphone,donation_main.group_donation_manager,1,1,1,1a \ No newline at end of file diff --git a/views/address.xml b/views/address.xml index 42fa847..6050a22 100644 --- a/views/address.xml +++ b/views/address.xml @@ -3,7 +3,7 @@ - + opendons_partneraddress list opendons.partneraddress @@ -20,7 +20,7 @@ - + opendons_partneraddress.search opendons.partneraddress @@ -30,7 +30,7 @@ - + opendons_partneraddress Form opendons.partneraddress diff --git a/views/email.xml b/views/email.xml new file mode 100644 index 0000000..b08f2a9 --- /dev/null +++ b/views/email.xml @@ -0,0 +1,64 @@ + + + + + + + opendons_partneremail list + opendons.partneremail + + + + + + + + + + + opendons_partneremail.search + opendons.partneremail + + + + + + + + + opendons_partneremail Form + opendons.partneremail + +
+ + + + + + + + + + + + +
+ + +
+
+
+
+ + + + + + + partneremails + opendons.partneremail + tree,form + + +
+
\ No newline at end of file diff --git a/views/mail_mail.xml b/views/mail_mail.xml new file mode 100644 index 0000000..91a9e70 --- /dev/null +++ b/views/mail_mail.xml @@ -0,0 +1,15 @@ + + + + operation.emailmarketing.opendons.form + mailing.mailing + + + + + + + + + + \ No newline at end of file diff --git a/views/operation.xml b/views/operation.xml index 4364d62..68740bb 100644 --- a/views/operation.xml +++ b/views/operation.xml @@ -1,10 +1,272 @@ + + Segments + opendons.segment + tree,form,graph + {'search_default_operation_id': active_id} + + + + Ensembles + opendons.ensemble + tree,form,graph + {'search_default_segment_id': active_id} + + + + Requests + opendons.request + tree,form,graph + {'search_default_ensemble_id': active_id} + + + + + opendons_operations list + opendons.operation + + + + + + + + + + + + + + + + + opendons_segment list + opendons.segment + + + + + + + + + + + + + + + opendons_segment.search + opendons.segment + + + + + + + + + opendons_ensemble list + opendons.ensemble + + + + + + + + + + + opendons_ensemble.search + opendons.ensemble + + + + + + + + + + + + opendons_request list + opendons.request + + + + + + + + + + + + opendons_request.search + opendons.request + + + + + + + + + + opendons_operation Form + opendons.operation + +
+
+
+ + + + + + + + + + + + +
+ +
+
+ + +
+
+
+
+ + + opendons_segment Form + opendons.segment + +
+ + + + + + + + + + + + +
+ +
+
+
+
+
+
+ + + opendons_ensemble Form + opendons.ensemble + +
+
+ + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+
+ + + opendons_request Form + opendons.request + +
+ + + + + + + + +
+
+
+ + + Opérations + opendons.operation + tree,form,pivot,graph + + + name="Operations"/> + + +
+ +
\ No newline at end of file diff --git a/views/partner.xml b/views/partner.xml index 30f08cd..07e1b62 100644 --- a/views/partner.xml +++ b/views/partner.xml @@ -1,6 +1,5 @@ - @@ -17,6 +16,28 @@ {'search_default_partner_id': active_id} + + Emails + opendons.partneremail + tree,form,graph + {'search_default_partner_id': active_id} + + + + phones + opendons.partnerphone + tree,form,graph + {'search_default_partner_id': active_id} + + + + + Relationships + opendons_relationship.partner + tree,form,graph + {'search_default_partner_id': active_id} + + qualifier.button.res.partner.form res.partner @@ -27,15 +48,33 @@ + + +
@@ -48,5 +87,10 @@ + + + + diff --git a/views/phone.xml b/views/phone.xml new file mode 100644 index 0000000..eb2b1b8 --- /dev/null +++ b/views/phone.xml @@ -0,0 +1,64 @@ + + + + + + + opendons_partnerphone list + opendons.partnerphone + + + + + + + + + + + opendons_partnerphone.search + opendons.partnerphone + + + + + + + + + opendons_partnerphone Form + opendons.partnerphone + +
+ + + + + + + + + + + + +
+ + +
+
+
+
+ + + + + + + partnerphones + opendons.partnerphone + tree,form + + +
+
\ No newline at end of file diff --git a/views/qualifier.xml b/views/qualifier.xml index c143dbf..e98f636 100644 --- a/views/qualifier.xml +++ b/views/qualifier.xml @@ -2,7 +2,7 @@ - + opendons_qualifier_category list opendons_qualifier.category @@ -14,14 +14,13 @@ - + opendons_qualifier list opendons_qualifier.qualifier - @@ -29,18 +28,19 @@ - + opendons_partnerqualifier list opendons_qualifier.partnerqualifier - + + - + opendons_partnerqualifier.search opendons_qualifier.partnerqualifier @@ -50,22 +50,19 @@ - + opendons_partnerqualifier Form opendons_qualifier.partnerqualifier
- -
diff --git a/views/relationship.xml b/views/relationship.xml new file mode 100644 index 0000000..f64b1d2 --- /dev/null +++ b/views/relationship.xml @@ -0,0 +1,113 @@ + + + + + + opendons_relationship_type list + opendons_relationship.type + + + + + + + + + + + opendons_relationship_nature list + opendons_relationship.nature + + + + + + + + + + + + opendons_relationship_partner list + opendons_relationship.partner + + + + + + + + + + + + opendons_relationship_partner.search + opendons_relationship.partner + + + + + + + + + opendons_relationshipPartner Form + opendons_relationship.partner + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + relationshipTypes + opendons_relationship.type + tree,form + + + + relationshipNature + opendons_relationship.nature + tree,form + + + + relationshipPartner + opendons_relationship.partner + tree,form + + + + + + +
+
\ No newline at end of file