# -*- coding: utf-8 -*- from odoo import models, fields, api, _ from odoo.exceptions import UserError, ValidationError from dateutil.relativedelta import relativedelta from datetime import datetime, timedelta import base64 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): if 'known_applicants_ids' not in vals and 'partner_id' in vals: if vals['partner_id']: vals['known_applicants_ids'] = [(4, vals['partner_id'])] return super(Ecarre_Lead, self).create(vals) class ActeSare(models.Model): _description = 'Actes' _name = 'ecarre.act.sare' # _inherit = ['mail.thread'] _inherit = ['mail.activity.mixin', 'mail.thread'] _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)] lead_id = fields.Many2one('crm.lead', string='Dossier', ondelete='cascade', index=True, copy=True) 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) partner_id = fields.Many2one('res.partner', string='Demandeur', required=True, ondelete='cascade', index=True, copy=True) 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) occupant_status_id = fields.Many2one('crm.occupant.status', string='Type public', domain=[('active', '=', True)]) building_type_id = fields.Many2one('sare.building.type', string='Type de bâtiment', domain=[('active', '=', True)]) resource_ceiling_id = fields.Many2one('resource.ceiling',related='partner_id.resource_ceiling_id',string="Plafond de ressources", store=True, compute_sudo=True) 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) duration = fields.Float('Durée (HH:MM)', required=False, default=False) verif_required_fields = fields.Boolean(compute='_compute_verif_fields', store=True, compute_sudo=True) validated = fields.Boolean('Validé', copy = False) # 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') support_abandonment_date = fields.Date('Date Abandon accompagnement') duration_service = fields.Float('Temps passé lors de l\'accompagnement / la prestation de MOE (jours)', compute='_compute_duration_service') 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") occupant_status_partner = fields.Selection([('PROPRIETAIRE', 'Propriétaire'),('LOCATAIRE', 'Locataire')],"Statut d'occupation du demandeur", default='PROPRIETAIRE') # 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") can_be_exported = fields.Boolean('Exportable', copy = False) exported = fields.Boolean('Exporté', copy = False) # 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)") 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") 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")) 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) _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.') ] @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 @api.one @api.depends('initial_need') def _compute_display_other(self): self.display_other = False if self.env.ref('ecarre_sare.intial_need_oher',False) in self.initial_need: self.display_other = True @api.depends('street', 'street2', 'zip', 'city') def _compute_address(self): for act in self: act.full_address = ' '.join([display_char(act.street),display_char(act.street2),display_char(act.zip),display_char(act.city)]) @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 @api.model def create(self, vals): # _logger.info("vals %r", vals) if 'verif_required_fields' not in vals: self._compute_verif_fields() vals['verif_required_fields'] = self.verif_required_fields if not vals['verif_required_fields']: raise ValidationError(_("Merci de vérifier les champs obligatoires.")) 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.")) 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 vals['can_be_exported'] = True """ 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']) partner = self.env['res.partner'].browse(vals['partner_id']) if lead and partner: lead.known_applicants_ids = lead.known_applicants_ids | partner return super(ActeSare, self).create(vals) def _onchange_partner_id_values(self, partner_id): """ returns the new values when partner_id has changed """ context = self._context or {} if partner_id and not context.get('default_lead_id', False): 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) @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.")) @api.multi def validate_act(self): if self.duration == 0: raise ValidationError(_("La durée de l'acte doit être supérieure à 0 pour valider l'acte.")) 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.")) return self.write({'validated': True}) def generate_lines(self,actes): datas = [] type_lgt_ademe = {'maison':'LI', 'appart':'LC', 'other':'CO'} for acte in actes: if not acte.phone and not acte.email: acte.validated = False continue if acte.type_housing == 'other' and not acte.lead_id.copro_nb_lots: acte.validated = False continue type_info = '_/_'.join([str(i.ademe_code) for i in acte.request_type]) nature_info = '_/_'.join([str(i.ademe_code) for i in acte.request_nature]) vals = { '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), 'd_015': display_char(acte.phone)[:20], 'd_016': type_lgt_ademe[acte.type_housing], 'd_017': acte.type_housing == 'other' and acte.lead_id.copro_nb_lots or '', 'd_018': display_char(acte.zip), 'd_019': display_char(acte.city), 'd_020': (display_char(acte.street) + ' ' + display_char(acte.street2)), 'd_021': acte.family_id == self.env.ref('ecarre_sare.family_act_b',False) and acte.occupant_status_partner or '', '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 '', '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 '', '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), 'd_032': format_date_export(acte.support_abandonment_date), '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), 'd_038': format_date_export(acte.write_date), 'd_039': acte.lead_id.partner_insee_geoban and display_char(acte.lead_id.partner_insee_geoban) or '', } datas.append(vals) 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) self.cr_conseil_a2_doc_filename = "Compte rendu entretien.pdf" return True def display_initial_need(self): 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, #'custom_layout': "mail.mail_notification_paynow", '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, } @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')