crm_lead.py 32.9 KB
Newer Older
1
2
3
4
5
# -*- coding: utf-8 -*-

from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from dateutil.relativedelta import relativedelta
6
7
8
from datetime import datetime, timedelta
import base64

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import logging
_logger = logging.getLogger(__name__)

fields_act_A1 = ['request_type','request_nature','request_question','request_response']
fields_act_A2 = ['service_envisaged_id']
fields_act_A3 = ['visa_advisor']
fields_act_A4 = ['sign_commitment_date','start_works_date','support_abandonment','duration_service','first_visit_date','first_sale_date']
fields_act_A4bis = ['sign_commitment_date','start_works_date','end_work_report_date','support_abandonment','duration_service','first_sale_date','consumption_balance','airtightness_test_date','final_handling_date']
fields_act_A5 = ['sign_commitment_date','start_works_date','end_work_report_date','support_abandonment','duration_service']
fields_act_B1 = ['siret','lastname_act','firstname_act','request_type','request_nature','request_question','request_response']
fields_act_B2 = ['siret','lastname_act','firstname_act','request_nature','service_envisaged_id']
fields_act_C1 = ['animation_type_id','duration_animation']
fields_act_C2 = ['animation_type_id','duration_animation']

def field_empty(vals, list):
    for item in list:
        vals[item] = False
    
    return vals
    
def display_char(string):
    if not string:
        return ''

    return str(string)
    
def format_date_export(date_string):
    if not date_string:
        return ''
    
    return date_string.strftime('%Y-%m-%d')
    

class Ecarre_Lead(models.Model):
    _inherit = "crm.lead"
        
    @api.depends('partner_id','known_applicants_ids')
    def _get_domain_applicant(self):
        for object in self:
            object.applicants_list = False
            available_applicants = self.env['res.partner'].search([('supplier', '=', True)])
            if object.partner_id:
                available_applicants = object.partner_id | available_applicants            
            object.applicants_list = [(6, 0, available_applicants.ids)]
        
    
    ## ACTES
    lead_act_sare_ids = fields.One2many('ecarre.act.sare', 'lead_id', string="Actes")
    lead_act_sare_a_ids = fields.One2many('ecarre.act.sare', 'lead_id', 
        string="Actes A", domain= lambda self: [("family_id", "=", self.env.ref("ecarre_sare.family_act_a").id)] )
    lead_act_sare_b_ids = fields.One2many('ecarre.act.sare', 'lead_id', 
        string="Actes B", domain= lambda self: [("family_id", "=", self.env.ref("ecarre_sare.family_act_b").id)] )
    consent_text = fields.Text(related='company_id.consent_text')
    applicants_list = fields.Many2many('res.partner', 'crm_lead_applicants_list',store=True,compute=_get_domain_applicant)
    known_applicants_ids = fields.Many2many('res.partner', 'crm_lead_known_applicants', string="Demandeur(s) connu(s)")
    
    nb_household_members = fields.Integer("Nombre de membres du foyer fiscal")
    reference_tax_income = fields.Integer("Revenu fiscal de référence")
    ## copro
    copro_nb_lots = fields.Integer("Nombre de lots")
    copro_register_number = fields.Char("Numéro de registre des copropriétés")  
    copro_nb_housing = fields.Integer('Nb logts copro')
    copro_nb_building = fields.Integer("Nombre de bâtiments")
    copro_nb_floor = fields.Integer("Nombre total d'étages de la copropriété")
            
    building_type_id = fields.Many2one('sare.building.type', string='Type de bâtiment', domain=[('active', '=', True)])
            
    @api.onchange('partner_id')
    def _onchange_partner_id(self):
        super(Ecarre_Lead, self)._onchange_partner_id()
        values = {'known_applicants_ids': False}
        if self.partner_id:
            values = {'known_applicants_ids': [(4, self.partner_id.id)]}
        self.update(values)

    @api.model
    def create(self, vals):
86
87
88
        if 'known_applicants_ids' not in vals and 'partner_id' in vals:
            if vals['partner_id']:
                vals['known_applicants_ids'] = [(4, vals['partner_id'])]
89
90
91
92
93
94
        return super(Ecarre_Lead, self).create(vals)
    

class ActeSare(models.Model):
    _description = 'Actes'
    _name = 'ecarre.act.sare'
95
    # _inherit = ['mail.thread']
96
    _inherit = ['mail.activity.mixin', 'mail.thread']
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    _order = 'act_date desc, id desc'
    
    @api.depends('partner_id')
    def _get_domain_applicant(self):
        for object in self:
            domain = []
            context = self._context or {}
            if context.get('default_lead_id', False):
                domain = [('supplier', '=', True)]
            
            available_applicants = self.env['res.partner'].search(domain)
            if object.lead_id.known_applicants_ids:
                available_applicants = object.lead_id.known_applicants_ids | available_applicants                
            object.applicants_list = [(6, 0, available_applicants.ids)]
    
112
    lead_id = fields.Many2one('crm.lead', string='Dossier', ondelete='cascade', index=True, copy=True)
113
114
    company_id = fields.Many2one('res.company', string='Structure', index=True, default=lambda self: self.env.user.company_id.id)
    applicants_list = fields.Many2many('res.partner', 'ecarre_act_sare_applicants_list',store=True,compute=_get_domain_applicant)
115
    partner_id = fields.Many2one('res.partner', string='Demandeur', required=True, ondelete='cascade', index=True, copy=True)
116
117
118
119
120
121
122
123
124
125
126
127
128
    lastname = fields.Char(related='partner_id.lastname',string='Nom', store=True, compute_sudo=True)
    firstname = fields.Char(related='partner_id.firstname',string='Prénom', store=True, compute_sudo=True)
    tiers = fields.Boolean(related='partner_id.is_company',string='Est une entreprise' ,store=True, compute_sudo=True, default=False)
    email = fields.Char(related='partner_id.email',string='Email', store=True, compute_sudo=True)
    phone = fields.Char(related='partner_id.phone',string='Téléphone', store=True, compute_sudo=True)
    anah_aid = fields.Boolean('Aide Habiter Mieux Sérénité')    
    type_housing = fields.Selection([('maison', _('Logement individuel')),('appart', _('Logement en copropriété')),('other', _('Copropriété'))],string='Type logement')
    nb_housing = fields.Integer('Nb logts copro')
    street = fields.Char(string='Rue')
    street2 = fields.Char(string='Rue 2')
    zip = fields.Char(string='Code postal')
    city = fields.Char(string='Ville')
    full_address = fields.Char(string='Adresse complète', compute='_compute_address', store=True, compute_sudo=True)
129
    occupant_status_id = fields.Many2one('crm.occupant.status', string='Type public', domain=[('active', '=', True)])
130
    building_type_id = fields.Many2one('sare.building.type', string='Type de bâtiment', domain=[('active', '=', True)])
131
    resource_ceiling_id = fields.Many2one('resource.ceiling',related='partner_id.resource_ceiling_id',string="Plafond de ressources", store=True, compute_sudo=True)
132
133
134
135
136
137
138
    
    family_id = fields.Many2one('crm.family.act.sare', string='Famille acte', index=True, required=True, ondelete='restrict')
    type_id = fields.Many2one('crm.type.act.sare', string='Type acte', index=True, required=True, ondelete='restrict')
    family_read = fields.Char(related='family_id.name', string='Famille acte (aff.)', store=True, readonly=True)
    type_read = fields.Char(related='type_id.display_name', string='Type acte (aff.)', store=True, readonly=True)
    
    act_date = fields.Date('Date',default=fields.Date.context_today, required=True) 
139
    duration = fields.Float('Durée (HH:MM)', required=False, default=False)    
140
    verif_required_fields = fields.Boolean(compute='_compute_verif_fields', store=True, compute_sudo=True)
141
    validated = fields.Boolean('Validé', copy = False)
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    # A1
    contact_type_id = fields.Many2one('crm.contact.type.act.sare', string='Type de contact', domain=[('active', '=', True)])
    request_type = fields.Many2many('crm.request.type', string='Type information', domain=[('active', '=', True)], required=False)
    request_nature = fields.Many2many('sare.request.nature', string='Nature information/conseil', domain=[('active', '=', True)], required=False)    
    request_question = fields.Text(_('Question'), required=False)
    request_response = fields.Text(_('Réponse'), required=False)
    # A2
    service_envisaged_id = fields.Many2one('crm.service.act.sare',string='Poursuite envisagée')
    # A3
    visa_advisor = fields.Selection([('oui', 'Oui'),('non', 'Non')],"Visa conseiller")
    # A4 / A4 bis
    sign_commitment_date = fields.Date('Date de signature engagement')
    start_works_date = fields.Date('Date de démarrage des travaux')
    end_work_report_date = fields.Date('Date du bilan de fin de travaux')
    support_abandonment = fields.Selection([('oui', 'Oui'),('non', 'Non')],"Abandon de l\'accompagnement", default='non')
157
    support_abandonment_date = fields.Date('Date Abandon accompagnement')
158
    duration_service = fields.Float('Temps passé lors de l\'accompagnement / la prestation de MOE (jours)', compute='_compute_duration_service')
159
160
161
162
163
164
165
166
167
168
    first_visit_date = fields.Date('Date de 1ere visite')
    first_sale_date = fields.Date('Date de 1er devis')
    consumption_balance = fields.Selection([('oui', 'Oui'),('non', 'Non')],"Bilan de consommation", default='oui')
    # A4 bis
    airtightness_test_date = fields.Date('Date du test d\'étanchéité à l\'air')
    final_handling_date = fields.Date("Date de Prise en main finale")
    # B1 / B2
    siret = fields.Char(related='partner_id.siret',string='SIRET', store=True, compute_sudo=True)
    lastname_act = fields.Char("Nom du contact")
    firstname_act = fields.Char("Prénom du contact")
169
    occupant_status_partner = fields.Selection([('PROPRIETAIRE', 'Propriétaire'),('LOCATAIRE', 'Locataire')],"Statut d'occupation du demandeur", default='PROPRIETAIRE')
170
171
172
173
174
175
176
    
    # C1
    animation_type_id = fields.Many2one('sare.animation.type',string='Type animation')
    duration_animation = fields.Float('Temps consacré à l\'animation')
    nb_people_sensitized = fields.Integer("Nombre de personnes sensibilisées")
    nb_professionals_mobilized = fields.Integer("Nombre de professionnels mobilisés")   
    
177
178
    can_be_exported = fields.Boolean('Exportable', copy = False)
    exported = fields.Boolean('Exporté', copy = False)
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    
    # Livrables
    cr_conseil_a2_doc = fields.Binary(string="CR Conseil personnalisé")
    cr_conseil_a2_doc_filename = fields.Char(string="Nom fichier pour CR Conseil personnalisé")    
    report_audit_a3_doc = fields.Binary(string="Rapport d'Audit")
    report_audit_a3_doc_filename = fields.Char(string="Nom fichier pour Rapport d'Audit")    
    engagement_doc = fields.Binary(string="Engagement")
    engagement_doc_filename = fields.Char(string="Nom fichier pour Engagement")    
    end_work_report_doc = fields.Binary(string="Bilan de fin de travaux")
    end_work_report_doc_filename = fields.Char(string="Nom fichier pour Bilan de fin de travaux")   
    cr_visit_a4_doc = fields.Binary(string="CR visite")
    cr_visit_a4_doc_filename = fields.Char(string="Nom fichier pour CR visite") 
    sale_doc = fields.Binary(string="Devis")
    sale_doc_filename = fields.Char(string="Nom fichier pour Devis")
    cr_follow_site_doc = fields.Binary(string="CR suivi de chantier")
    cr_follow_site_doc_filename = fields.Char(string="Nom fichier pour CR suivi de chantier")
    consumption_balance_doc = fields.Binary(string="Bilan de consommation")
    consumption_balance_doc_filename = fields.Char(string="Nom fichier pour Bilan de consommation")
    cr_airtightness_test_doc = fields.Binary(string="CR étanchéité à l'air")
    cr_airtightness_test_doc_filename = fields.Char(string="Nom fichier pour CR étanchéité à l'air")
    cr_final_handling_doc = fields.Binary(string="CR prise en main finale")
    cr_final_handling_doc_filename = fields.Char(string="Nom fichier pour CR prise en main finale")
    cr_request_info_doc = fields.Binary(string="CR Demande d'information")
    cr_request_info_doc_filename = fields.Char(string="Nom fichier pour CR Demande d'information")
    energy_prediagnosis_doc = fields.Binary(string="Pré-diagnostic énergétique remis à l'entreprise")
    energy_prediagnosis_doc_filename = fields.Char(string="Nom fichier pour Pré-diagnostic énergétique remis à l'entreprise")
    
    # champs complémentaires
    consumption_initial = fields.Integer("Consommation initiale (élec - gaz - bois - fuel)")
    consumption_after_work = fields.Integer("Consommation 2 ans après la fin des travaux (élec - gaz - bois - fuel)")
209
210
211
212
    consumption_dpe_initial = fields.Integer("Consommation DPE initiale")
    consumption_ges_initial = fields.Integer("GES initiale")
    consumption_dpe_after_work = fields.Integer("Consommation DPE 2 ans après la fin des travaux")
    consumption_ges_after_work = fields.Integer("GES 2 ans après la fin des travaux")
213
    
214
215
216
217
218
219
220
221
222
223
224
225
    initial_need = fields.Many2many('sare.initial.need', string="Besoin initial du demandeur", domain=[('active', '=', True)])
    display_other = fields.Boolean("display other", compute='_compute_display_other', store=True)
    other_need = fields.Text(_("Autre besoin"))
    expectations = fields.Text(_("Attentes du demandeur"))
    specific_constraints = fields.Text(_("Contraintes particulières"))
    envelope_work = fields.Text(_("Travaux d’amélioration de l’enveloppe"))
    system_work = fields.Text(_("Travaux d’amélioration des systèmes"))
    other_work = fields.Text(_("Autres Travaux"))
    advisor_opinion = fields.Text(_("L’avis du/de la conseiller(ère) sur le projet"))
    simul_aide = fields.Boolean("Simulation Simul’aide réalisée au cours de l’entretien")
    next_step = fields.Text(_("Prochaine étape du projet"))
    
226
227
228
229
    emitting_company_id = fields.Many2one('res.company', string='Structure émétrice', index=True, 
        default=lambda self: self.env.user.company_id.id, 
        domain=lambda self: [("id", "child_of", self.env.user.company_id.id)],
        check_company=True)
230
    
231
232
233
    _sql_constraints = [
        ('acte_date_greater', 'check(start_works_date >= sign_commitment_date)', 'Erreur! la date de début de travaux doit être supérieur à la date d\'engagement.')
    ]
234
    
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    @api.model
    def default_get(self, fields):
        rec = super(ActeSare, self).default_get(fields)
        
        context = self._context or {}
        if context.get('default_lead_id', False):
            lead = self.env['crm.lead'].sudo().browse(context['default_lead_id'])
            if lead:
                rec.update(
                    {'partner_id': lead.partner_id.id, 
                    'anah_aid': lead.anah_aid, 
                    'type_housing': lead.type_housing, 
                    'nb_housing': lead.copro_nb_housing, 
                    'street': lead.street, 
                    'street2': lead.street2, 
                    'zip': lead.zip, 
                    'city': lead.city, 
                    'occupant_status_id': lead.occupant_status_id.id,
                    'building_type_id': lead.building_type_id.id,
                    }
                )        
        return rec
    
    @api.one
    @api.depends('lastname', 'firstname', 'phone', 'email', 'street', 'street2', 'zip', 'city', 'siret')
    def _compute_verif_fields(self):
        self.verif_required_fields = True
        if (not self.lastname or not self.firstname) and not self.tiers:
            self.verif_required_fields = False
        if (not self.phone and not self.email)or (not self.street and not self.street2) or not self.zip or not self.city:
            self.verif_required_fields = False
        if self.tiers and not self.siret:
            self.verif_required_fields = False
            
269
270
271
272
    @api.one
    @api.depends('initial_need')
    def _compute_display_other(self):
        self.display_other = False
273
        if self.env.ref('ecarre_sare.intial_need_oher',False) in self.initial_need:
274
275
            self.display_other = True
            
276
277
    @api.depends('street', 'street2', 'zip', 'city')
    def _compute_address(self):
278
        for act in self:
279
280
            act.full_address = ' '.join([display_char(act.street),display_char(act.street2),display_char(act.zip),display_char(act.city)])
    
281
282
283
284
285
286
287
    @api.depends('sign_commitment_date','start_works_date')
    def _compute_duration_service(self):
        for act in self:
            act.duration_service = 0.0
            if act.start_works_date and act.sign_commitment_date:
                act.duration_service = (fields.Date.from_string(act.start_works_date) - fields.Date.from_string(act.sign_commitment_date)).days
    
288
    @api.model
289
    def create(self, vals):                
290
        # _logger.info("vals %r", vals)
291
292
293
294
        if 'verif_required_fields' not in vals:
            self._compute_verif_fields()
            vals['verif_required_fields'] = self.verif_required_fields
            
295
296
297
        if not vals['verif_required_fields']:
            raise ValidationError(_("Merci de vérifier les champs obligatoires."))
        
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
        if 'family_id' not in vals or 'type_id' not in vals:
            raise ValidationError(_("La famille et le type d'acte sont obligatoires."))
            
        if 'lead_id' in vals:
            if vals['family_id'] == self.env.ref('ecarre_sare.family_act_a',False).id:
                # famille A, maximum 2 actes A2 ou un acte des autres types (hormis A1)
                if vals['type_id'] == self.env.ref('ecarre_sare.type_act_a2',False).id:
                    if self.search_count([('lead_id', '=', vals['lead_id']), ('type_id', '=', self.env.ref('ecarre_sare.type_act_a2',False).id)]) == 2:
                        raise ValidationError(_("Vous ne pouvez pas avoir plus de deux actes A2 pour un dossier."))
                    
                elif vals['type_id'] != self.env.ref('ecarre_sare.type_act_a1',False).id:
                    if self.search_count([('lead_id', '=', vals['lead_id']), ('type_id', '=', vals['type_id'])]) == 1:
                        raise ValidationError(_("Vous ne pouvez pas avoir plus d'un acte de ce type pour un dossier."))
            
            if vals['type_id'] == self.env.ref('ecarre_sare.type_act_b2',False).id:
                date_m8 = fields.Date.today() + relativedelta(months=-8)                
                if self.search_count([('lead_id', '=', vals['lead_id']), ('type_id', '=', self.env.ref('ecarre_sare.type_act_b2',False).id), ('act_date', '>=', date_m8)]) > 0:
                    raise ValidationError(_("Vous ne pouvez pas avoir plus d\'un acte B2 pour un dossier en moins de 8 mois."))
316
        
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
        if 'lead_id' not in vals:
            values_lead = {}
            values_lead['partner_id'] = vals['partner_id']
            values_lead['type_housing'] = vals['type_housing']
            values_lead['anah_aid'] = vals['anah_aid']
            values_lead['occupant_status_id'] = vals['occupant_status_id']
            values_lead['street'] = vals['street']          
            values_lead['street2'] = vals['street2']
            values_lead['zip'] = vals['zip']
            values_lead['city'] = vals['city']
            vals['lead_id'] = self.env['crm.lead'].create(values_lead)
        
        if vals['type_id'] == self.env.ref('ecarre_sare.type_act_a1',False).id or vals['type_id'] == self.env.ref('ecarre_sare.type_act_b1', False).id:
            # on valide l'acte
            vals['validated'] = True
332
            vals['can_be_exported'] = True
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
        
        """ on vide les autres champs qui ne correspondent pas au type d'acte créé pour ne pas fausser les stats """
        list_fields = False
        if vals['type_id'] == self.env.ref('ecarre_sare.type_act_a1',False).id:
            # A1
            list_fields = list(set(fields_act_A2 + fields_act_A3 + fields_act_A4 + fields_act_A4bis + fields_act_A5 + fields_act_B1 + fields_act_B2 + fields_act_C1 + fields_act_C2).difference(set(fields_act_A1)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_a2',False).id:
            # A2
            list_fields = list(set(fields_act_A1 + fields_act_A3 + fields_act_A4 + fields_act_A4bis + fields_act_A5 + fields_act_B1 + fields_act_B2 + fields_act_C1 + fields_act_C2).difference(set(fields_act_A2)))            
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_a3',False).id:
            # A3
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A4 + fields_act_A4bis + fields_act_A5 + fields_act_B1 + fields_act_B2 + fields_act_C1 + fields_act_C2).difference(set(fields_act_A3)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_a4',False).id:
            # A4
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A3 + fields_act_A4bis + fields_act_A5 + fields_act_B1 + fields_act_B2 + fields_act_C1 + fields_act_C2).difference(set(fields_act_A4)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_a4b',False).id:
            # A4bis
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A3 + fields_act_A4 + fields_act_A5 + fields_act_B1 + fields_act_B2 + fields_act_C1 + fields_act_C2).difference(set(fields_act_A4bis)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_a5',False).id:
            # A5
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A3 + fields_act_A4 + fields_act_A4bis + fields_act_B1 + fields_act_B2 + fields_act_C1 + fields_act_C2 ).difference(set(fields_act_A5)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_b1',False).id:
            # B1
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A3 + fields_act_A4 + fields_act_A4bis + fields_act_A5 + fields_act_B2 + fields_act_C1 + fields_act_C2).difference(set(fields_act_B1)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_b2',False).id:
            # B2
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A3 + fields_act_A4 + fields_act_A4bis + fields_act_A5 + fields_act_B1 + fields_act_C1 + fields_act_C2).difference(set(fields_act_B2)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_c1',False).id:
            # C1
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A3 + fields_act_A4 + fields_act_A4bis + fields_act_A5 + fields_act_B1 + fields_act_B2 + fields_act_C2).difference(set(fields_act_C1)))
        elif vals['type_id'] == self.env.ref('ecarre_sare.type_act_c2',False).id:
            # C2
            list_fields = list(set(fields_act_A1 + fields_act_A2 + fields_act_A3 + fields_act_A4 + fields_act_A4bis + fields_act_A5 + fields_act_B1 + fields_act_B2 + fields_act_C1).difference(set(fields_act_C2)))

        vals = field_empty(vals,list_fields) 
        
        ## mise à jour des demandeurs sur le dossier
        lead = self.env['crm.lead'].browse(vals['lead_id'])
371
372
373
        partner = self.env['res.partner'].browse(vals['partner_id'])
        if lead and partner:
            lead.known_applicants_ids = lead.known_applicants_ids | partner
374
                
375
376
377
378
        return super(ActeSare, self).create(vals)
        
    def _onchange_partner_id_values(self, partner_id):
        """ returns the new values when partner_id has changed """
379
380
        context = self._context or {}
        if partner_id and not context.get('default_lead_id', False):
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
            partner = self.env['res.partner'].sudo().browse(partner_id)

            return {
                'street':partner.street, 
                'street2':partner.street2, 
                'zip':partner.zip, 
                'city':partner.city                
            }
        return {}
    
    @api.onchange('partner_id')
    def _onchange_partner_id(self):
        res = {'domain': {'lead_id': []}}
        if self.partner_id:
            values = self._onchange_partner_id_values(self.partner_id.id if self.partner_id else False)
            self.update(values)            
            res['domain']['lead_id'] = [('partner_id', '=', self.partner_id.id)]
        return res
        
    def _onchange_lead_id_values(self, lead_id):
        """ returns the new values when partner_id has changed """
        if lead_id:
            lead = self.env['crm.lead'].sudo().browse(lead_id)

            return {
                'anah_aid': lead.anah_aid,
                'occupant_status_id': lead.occupant_status_id,
                'type_housing':lead.type_housing,
                'street':lead.street, 
                'street2':lead.street2, 
                'zip':lead.zip, 
                'city':lead.city                
            }
        return {}
    
    @api.onchange('lead_id')
    def _onchange_lead_id(self):
        values = self._onchange_lead_id_values(self.lead_id.id if self.lead_id else False)
        self.update(values)
        
    @api.onchange('family_id')
    def _onchange_family_id(self):
        context = self._context or {}
        values = {'type_id': False}
        if self.family_id.id == context.get('default_family_id', False):
            values = {'type_id': context.get('default_type_id', False)}
        self.update(values)
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

    @api.onchange('type_id')
    def _onchange_type_id(self):    
        if self.family_id == self.env.ref('ecarre_sare.family_act_a',False):
            # famille A, maximum 2 actes A2 ou un acte des autres types (hormis A1)
            if self.type_id == self.env.ref('ecarre_sare.type_act_a2',False):
                if self.search_count([('lead_id', '=', self.lead_id.id), ('type_id', '=', self.env.ref('ecarre_sare.type_act_a2',False).id)]) == 2:
                    raise ValidationError(_("Vous ne pouvez pas avoir plus de deux actes A2 pour un dossier."))
                
            elif self.type_id != self.env.ref('ecarre_sare.type_act_a1',False):
                if self.search_count([('lead_id', '=', self.lead_id.id), ('type_id', '=', self.type_id.id)]) == 1:
                    raise ValidationError(_("Vous ne pouvez pas avoir plus d'un acte de ce type pour un dossier."))
            
        if self.type_id == self.env.ref('ecarre_sare.type_act_b2',False):
            date_m8 = fields.Date.today() + relativedelta(months=-8)                
            if self.search_count([('lead_id', '=', self.lead_id.id), ('type_id', '=', self.env.ref('ecarre_sare.type_act_b2',False).id), ('act_date', '>=', date_m8)]) > 0:
                raise ValidationError(_("Vous ne pouvez pas avoir plus d\'un acte B2 pour un dossier en moins de 8 mois."))
445
446
447
        
    @api.multi
    def validate_act(self):
448
449
450
        if self.duration == 0:
            raise ValidationError(_("La durée de l'acte doit être supérieure à 0 pour valider l'acte."))
        
451
452
453
454
455
456
457
458
459
460
461
462
463
        if self.type_id == self.env.ref('ecarre_sare.type_act_a2',False) and not self.service_envisaged_id:
            raise ValidationError(_("La poursuite envisagée est obligatoire pour valider l'acte."))
            
        if (
            self.type_id == self.env.ref('ecarre_sare.type_act_a4',False) or 
            self.type_id == self.env.ref('ecarre_sare.type_act_a4b',False) or 
            self.type_id == self.env.ref('ecarre_sare.type_act_a5',False) or 
            self.type_id == self.env.ref('ecarre_sare.type_act_a4copro',False) or 
            self.type_id == self.env.ref('ecarre_sare.type_act_a4bcopro',False) or 
            self.type_id == self.env.ref('ecarre_sare.type_act_a5copro',False)
            ) and not self.sign_commitment_date:
            raise ValidationError(_("La date de signature d'engagement est obligatoire pour valider l'acte."))
            
464
465
466
467
468
        return self.write({'validated': True})
        
    def generate_lines(self,actes):
        datas = []
        
469
470
        type_lgt_ademe = {'maison':'LI', 'appart':'LC', 'other':'CO'}
        
471
        for acte in actes:
472
473
474
            if not acte.phone and not acte.email:
                acte.validated = False
                continue
475
476
477
478
                
            if acte.type_housing == 'other' and not acte.lead_id.copro_nb_lots:
                acte.validated = False
                continue    
479
            
480
            type_info = '_/_'.join([str(i.ademe_code) for i in acte.request_type])
481
            nature_info = '_/_'.join([str(i.ademe_code) for i in acte.request_nature])
482
483
        
            vals = {
484
485
486
487
488
489
490
491
492
493
494
495
496
497
            'd_001': display_char(acte.id),
            'd_002': display_char(acte.company_id.ademe_code),
            'd_003': display_char(acte.create_uid.name),
            'd_004': acte.type_read,
            'd_005': acte.sign_commitment_date and format_date_export(acte.sign_commitment_date) or format_date_export(acte.act_date),
            'd_006': int(acte.duration)*60 + round((acte.duration % 1) * 60),
            'd_007': 'M',
            'd_008': display_char(acte.occupant_status_id.ademe_code),
            'd_009': display_char(acte.lastname),
            'd_010': display_char(acte.firstname),
            'd_011': acte.tiers and display_char(acte.partner_id.name) or '',
            'd_012': display_char(acte.siret),
            'd_013': (not acte.tiers and acte.anah_aid) and 'OUI' or 'NON',
            'd_014': display_char(acte.email),
498
            'd_015': display_char(acte.phone)[:20],
Jean-Christophe CHOQUET's avatar
Jean-Christophe CHOQUET committed
499
            'd_016': type_lgt_ademe[acte.type_housing],
500
            'd_017': acte.type_housing == 'other' and acte.lead_id.copro_nb_lots or '',
501
502
503
            'd_018': display_char(acte.zip),
            'd_019': display_char(acte.city),
            'd_020': (display_char(acte.street) + ' ' + display_char(acte.street2)),
Jean-Christophe CHOQUET's avatar
Jean-Christophe CHOQUET committed
504
            'd_021': acte.family_id == self.env.ref('ecarre_sare.family_act_b',False) and acte.occupant_status_partner or '',
505
506
507
            'd_022': type_info,
            'd_023': acte.type_id == self.env.ref('ecarre_sare.type_act_b1',False) and nature_info or (acte.type_id == self.env.ref('ecarre_sare.type_act_a1',False) and nature_info or ''),
            'd_024': acte.type_id == self.env.ref('ecarre_sare.type_act_b2',False) and nature_info or '',
508
509
            'd_025': acte.request_question and acte.request_question.replace("\n", " ")[:1000] or '',
            'd_026': acte.request_response and acte.request_response.replace("\n", " ")[:1000] or '',
510
511
512
513
514
            'd_027': acte.service_envisaged_id and acte.service_envisaged_id.ademe_code or '',
            'd_028': acte.report_audit_a3_doc and 'OUI' or 'NON',
            'd_029': acte.type_id == self.env.ref('ecarre_sare.type_act_a3',False) and acte.visa_advisor.upper() or '',
            'd_030': format_date_export(acte.start_works_date),
            'd_031': format_date_export(acte.end_work_report_date),
Jean-Christophe CHOQUET's avatar
Jean-Christophe CHOQUET committed
515
            'd_032': format_date_export(acte.support_abandonment_date),
516
517
518
519
520
            'd_033': format_date_export(acte.first_visit_date),
            'd_034': format_date_export(acte.first_sale_date),
            'd_035': format_date_export(acte.end_work_report_date),
            'd_036': format_date_export(acte.airtightness_test_date),
            'd_037': format_date_export(acte.final_handling_date),
521
            'd_038': format_date_export(acte.write_date),
522
            'd_039': acte.lead_id.partner_insee_geoban and display_char(acte.lead_id.partner_insee_geoban) or '',
523
524
525
            }
            datas.append(vals)
            
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
        return datas
        
    @api.multi
    def print_cr_a2(self):
        return self.env.ref('ecarre_sare.action_report_cr_a2').with_context(discard_logo_check=True).report_action(self)
        
    @api.multi
    def print_and_attach_cr_a2(self):
        datas = {
             'model': 'ecarre.act.sare',
             'ids': [self.id],
        }
        result, formats = self.env.ref('ecarre_sare.action_report_cr_a2').render_qweb_pdf([self.id], data=datas)

        self.cr_conseil_a2_doc = base64.b64encode(result)
Jean-Christophe CHOQUET's avatar
Jean-Christophe CHOQUET committed
541
        self.cr_conseil_a2_doc_filename = "Compte rendu entretien.pdf"
542
543
544
545
        
        return True
        
    def display_initial_need(self):
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
        return ', '.join([str(i.name) for i in self.initial_need])
        
    @api.multi
    def action_cr_a2_send(self):
        '''
        This function opens a window to compose an email, with the template message loaded by default
        '''
        self.ensure_one()
        ir_model_data = self.env['ir.model.data']
        try:
            template_id = ir_model_data.get_object_reference('ecarre_sare', 'email_template_cr_a2')[1]
        except ValueError:
            template_id = False
        try:
            compose_form_id = ir_model_data.get_object_reference('mail', 'email_compose_message_wizard_form')[1]
        except ValueError:
            compose_form_id = False
        ctx = {
            'default_model': 'ecarre.act.sare',
            'default_res_id': self.ids[0],
            'default_use_template': bool(template_id),
            'default_template_id': template_id,
            'default_composition_mode': 'comment',
            'mark_so_as_sent': True,
570
            #'custom_layout': "mail.mail_notification_paynow",
571
572
573
574
575
576
577
578
579
580
581
            'force_email': True
        }
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'mail.compose.message',
            'views': [(compose_form_id, 'form')],
            'view_id': compose_form_id,
            'target': 'new',
            'context': ctx,
582
583
584
585
586
587
588
        }

    @api.multi
    def get_base_url(self):
        """Get the base URL for the current acte."""
        self.ensure_one()
        return self.env['ir.config_parameter'].sudo().get_param('web.base.url')
589
590