# Copyright 2021 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import base64 import json from odoo import api, models from odoo import fields as odooFields from odoo.addons.cmis_field import fields from odoo.exceptions import UserError class AccountInvoice(models.Model): _name = 'account.invoice' _inherit = ['account.invoice', 'lefilament.alfresco'] # ------------------------------------------------------ # Fields declaration # ------------------------------------------------------ project_id = odooFields.Many2one( 'project.project', string='Projet', change_default=True, readonly=True, states={'draft': [('readonly', False)]}, track_visibility='always', ondelete='restrict',) num_dossier = odooFields.Char(related="project_id.num_dossier") type_convention_id = odooFields.Many2one( "adefpat.type.convention", related="project_id.type_convention_id", string="Type de convention de financement", ) alfresco_file = odooFields.Char("Facture liée") cmis_folder = fields.CmisFolder( allow_create=True, allow_delete=False, ) task_ids = odooFields.One2many( "project.task", "invoice_id", string="Séances liées", ) partner_id_domain = odooFields.Char( compute="_compute_partner_id_domain", readonly=True, store=False, ) task_ids_domain = odooFields.Char( compute="_compute_task_ids_domain", readonly=True, store=False, ) amount_task_total = odooFields.Monetary( string='Total Séances', store=True, readonly=True, compute='_compute_amount_task_total') @api.one @api.depends('task_ids', 'task_ids.cout_seance') def _compute_amount_task_total(self): if self.type == "in_invoice": self.amount_task_total = sum( line.cout_seance for line in self.task_ids) @api.depends('project_id') def _compute_partner_id_domain(self): """ Crée un domaine dynamique pour les CF """ if self.type == "in_invoice": domain = [('is_consultant_form', '=', True)] if self.project_id: formateur_ids = self.env["project.task"].search( [("project_id", "=", self.project_id.id)] ).mapped("formateur_id") domain.append(('id', 'in', formateur_ids.ids)) self.partner_id_domain = json.dumps(domain) @api.depends('project_id', 'partner_id') def _compute_task_ids_domain(self): """ Crée un domaine dynamique pour les séances """ if self.type == "in_invoice": domain = [] dom = [] if self.project_id: dom.append(("project_id", "=", self.project_id.id)) if self.partner_id: dom.append(("formateur_id", "=", self.partner_id.id)) task_ids = self.env["project.task"].search(dom) domain.append(('id', 'in', task_ids.ids)) self.task_ids_domain = json.dumps(domain) # ------------------------------------------------------ # SQL Constraints # ------------------------------------------------------ # ------------------------------------------------------ # Default methods # ------------------------------------------------------ # ------------------------------------------------------ # Computed fields / Search Fields # ------------------------------------------------------ # ------------------------------------------------------ # Onchange / Constraints # ------------------------------------------------------ # ------------------------------------------------------ # CRUD methods (ORM overrides) # ------------------------------------------------------ @api.model def _prepare_refund(self, invoice, date_invoice=None, date=None, description=None, journal_id=None): values = super(AccountInvoice, self)._prepare_refund(invoice, date_invoice, date, description, journal_id) if invoice.project_id: values['project_id'] = invoice.project_id.id return values # ------------------------------------------------------ # Actions # ------------------------------------------------------ @api.multi def generate_alfresco_file(self): """ Ajoute un fichier sur la GED Alfresco @return: fonction get_partner_files() de res.partner """ # Get proof folder nodeRef backend = self.env['cmis.backend'].search([], limit=1) # Si la facture a déjà été créée, ouvrir dans Alfresco if self.alfresco_file: prop = backend.get_cmis_repository().getFolder( self.alfresco_file).getProperties() url = backend.get_content_details_url_from_props(prop) # Sinon, la créer, puis la stocker ainsi que les documents liées à la facture dans Alfresco else: project_folder = self.project_id.cmis_folder self.cmis_folder = project_folder if not project_folder: raise UserError("Le dossier du projet n'est pas configuré") # Get Mimetype attachment = self.env.ref('account.account_invoices').retrieve_attachment(self) if not attachment: raise UserError("La facture n'a pas encore été générée. Imprimer la facture pour pouvoir la visualiser dans Alfresco") content_type = attachment.mimetype path_proj = backend.get_cmis_repository().getFolder( project_folder).getPaths() # Get template doc Facture template_doc = self.env['adefpat.template.doc'].search([ ('type_temp', '=', 'facture'), ('noderef_document', '=', False)]) # Get doc linked to Facture template_doc_ids = self.env['adefpat.template.doc'].search([ ('type_temp', '=', 'facture'), ('noderef_document', '!=', False)]) # Strore template in Alfresco for template in template_doc_ids: keys = self.fill_data() self._publipostage_documents(template, keys, False) path_n0 = path_proj + [template_doc.dossier.name] path = '/'.join(path_n0) cmis_obj = backend.get_folder_by_path(path) file = cmis_obj.createDocument( name=attachment.name, properties={}, contentFile=base64.b64decode(attachment.datas), contentType=content_type ) file_id = file.getProperties().get('cmis:objectId') self.alfresco_file = file.getObjectId() prop = backend.get_cmis_repository().getFolder( file_id).getProperties() url = backend.get_content_details_url_from_props(prop) return { 'type': 'ir.actions.act_url', 'url': url, 'target': 'new', } # ------------------------------------------------------ # Business methods # ------------------------------------------------------ def fill_data(self): parser = [ ('partner_id:name_benef', ['name']), ('partner_id:title_benef', [('title', ['name'])]), ('partner_id:zip_benef', ['zip']), ('partner_id:city_benef', ['city']), ('partner_id:street_benef', ['street']), ('project_id:cfd_name', [('user_id', ['name'])]), ('project_id:cfd_mobile', [('user_id', ['mobile'])]), ('project_id:project_name', ['name']), 'amount_total:montant', 'date_invoice:date', ] keys = self.json_build(parser)[0] return keys