diff --git a/TODOLIST.md b/TODOLIST.md new file mode 100644 index 0000000..01f3874 --- /dev/null +++ b/TODOLIST.md @@ -0,0 +1,11 @@ +# TODO LIST + +## Features + +## Fixes + - Change all `parents` to `genitive` + - Merge `document_type` and `template_type` in `res.partner.document.template` + - Change `annex_number` to `annex_counter` + +## Big feature + - Separate XML actions that generates transient fields for all types of documents diff --git a/__manifest__.py b/__manifest__.py index 2a1bc8b..bfe6d85 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -19,6 +19,7 @@ "security/ir.model.access.csv", "views/res_partner_contract.xml", "views/res_partner_contract_annex.xml", + "views/res_partner_contract_field.xml", "views/res_partner_document_template.xml", "views/res_partner.xml", "views/sale_order.xml", diff --git a/data/fields_default.xml b/data/fields_default.xml index 972ccbc..12633a3 100644 --- a/data/fields_default.xml +++ b/data/fields_default.xml @@ -155,8 +155,8 @@ action = ctx # Aliases self = record -seller = self.contract_id.company_id -partner = self.contract_id.partner_id +seller = self.company_id +partner = self.partner_id seller_bank = seller.bank_ids and seller.bank_ids[0] seller_bank_name = seller_bank.bank_id.name + (" г. {city}".format(city=seller_bank.bank_id.city) if seller_bank.bank_id.city else "") @@ -191,7 +191,7 @@ ctx = { "contract_number": self.contract_id.name, "annex_name": self.name, - "annex_number": self.number, + "annex_number": self.counter, "order_name": self.order_id.name, "order_date": "{} {} {}".format(order_date.day, months[order_date.month], order_date.year), diff --git a/i18n/ru.po b/i18n/ru.po index 4356772..9abc06a 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0-20191106\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-01-21 14:27+0000\n" -"PO-Revision-Date: 2020-01-21 14:27+0000\n" +"POT-Creation-Date: 2020-01-22 11:29+0000\n" +"PO-Revision-Date: 2020-01-22 11:29+0000\n" "Last-Translator: Stepan Savelyev\n" "Language-Team: RYDLAB\n" "MIME-Version: 1.0\n" @@ -42,14 +42,14 @@ msgid "3 stages" msgstr "Оплата в 3 этапа" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:28 +#: code:addons/client_contracts/models/res_partner_document_template.py:31 #: selection:res.partner.document.template,document_type_name:0 #, python-format msgid "Act of Acceptance and Delivery" msgstr "Акт сдачи-приемки" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:27 +#: code:addons/client_contracts/models/res_partner_document_template.py:30 #: selection:res.partner.document.template,document_type_name:0 #, python-format msgid "Act of Acceptance and Transfer" @@ -62,7 +62,7 @@ msgid "Actual Address" msgstr "Актуальный адрес" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:18 +#: code:addons/client_contracts/models/res_partner_document_template.py:21 #: selection:res.partner.document.template,document_type:0 #, python-format msgid "Addition" @@ -79,7 +79,7 @@ msgid "Amount Whole Part" msgstr "Целая часть суммы" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:17 +#: code:addons/client_contracts/models/res_partner_document_template.py:20 #: selection:res.partner.document.template,document_type:0 #: selection:res.partner.document.template,template_type:0 #, python-format @@ -112,7 +112,7 @@ msgid "Annexes to this contract" msgstr "Приложения к договору" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:26 +#: code:addons/client_contracts/models/res_partner_document_template.py:29 #: selection:res.partner.document.template,document_type_name:0 #, python-format msgid "Approval List" @@ -147,7 +147,7 @@ msgid "Bank Payment Account" msgstr "Расчётный счёт" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:24 +#: code:addons/client_contracts/models/res_partner_document_template.py:27 #: selection:res.partner.document.template,document_type_name:0 #, python-format msgid "Bill" @@ -175,6 +175,7 @@ msgid "Closed" msgstr "Закрыт" #. module: client_contracts +#: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_annex_company_id #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_company_id #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_wizard_company_id msgid "Company" @@ -196,7 +197,7 @@ msgid "Contact" msgstr "Контакт" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:16 +#: code:addons/client_contracts/models/res_partner_document_template.py:19 #: model:ir.model,name:client_contracts.model_res_partner_contract #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_annex_contract_id #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_field_transient__contract_wizard_id @@ -233,6 +234,7 @@ msgid "Contract Field Transient" msgstr "Фактическое поле договора" #. module: client_contracts +#: model:ir.actions.act_window,name:client_contracts.res_partner_contract_field_action #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_wizard_transient_field_ids msgid "Contract Fields" msgstr "Поля договора" @@ -269,7 +271,7 @@ msgid "Counter for generate Annex name" msgstr "Счётчик для генерации имени приложения к договору" #. module: client_contracts -#: model:ir.model.fields,help:client_contracts.field_res_partner_contract_annex_number +#: model:ir.model.fields,help:client_contracts.field_res_partner_contract_annex_counter msgid "Counter of Contract Annexes" msgstr "Счётчик приложений к договору" @@ -303,6 +305,11 @@ msgstr "Создано" msgid "Created on" msgstr "Создан" +#. module: client_contracts +#: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_annex_currency_id +msgid "Currency" +msgstr "Валюта" + #. module: client_contracts #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_date_conclusion_fix msgid "Date of manual conclusion" @@ -391,6 +398,11 @@ msgstr "Имя документа" msgid "Document Template" msgstr "Шаблон документа" +#. module: client_contracts +#: model:ir.actions.act_window,name:client_contracts.res_partner_document_template_action +msgid "Document Templates" +msgstr "Шаблоны документов" + #. module: client_contracts #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_annex_design_doc_cost msgid "Documentation Design Cost" @@ -828,7 +840,7 @@ msgid "Print Form of Contract" msgstr "Форма печати договора" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_contract_annex.py:104 +#: code:addons/client_contracts/models/res_partner_contract_annex.py:111 #, python-format msgid "Print Form of Contract Annex" msgstr "Форма печати приложения к договору" @@ -952,7 +964,7 @@ msgid "Sole Proprietor" msgstr "Индивидуальный предприниматель" #. module: client_contracts -#: code:addons/client_contracts/models/res_partner_document_template.py:25 +#: code:addons/client_contracts/models/res_partner_document_template.py:28 #: selection:res.partner.document.template,document_type_name:0 #, python-format msgid "Specification" @@ -1003,7 +1015,7 @@ msgid "Template Type" msgstr "Тип шаблона" #. module: client_contracts -#: model:ir.ui.menu,name:client_contracts.res_partner_menu_contracts_templates_ +#: model:ir.ui.menu,name:client_contracts.res_partner_menu_contracts_templates msgid "Templates" msgstr "Шаблоны" @@ -1028,6 +1040,11 @@ msgstr "Transient Field Ids Hidden" msgid "Type of document" msgstr "Вид документа" +#. module: client_contracts +#: model:ir.model.fields,help:client_contracts.field_res_partner_contract_annex_currency_id +msgid "Utility field to express amount currency" +msgstr "Служебное поле, чтобы выразить суммы в валюте" + #. module: client_contracts #: model:ir.model.fields,field_description:client_contracts.field_res_partner_contract_field_transient_value msgid "Value" @@ -1068,23 +1085,13 @@ msgstr "Год" msgid "i.e. Ural Bank for Reconstruction and Development" msgstr "напр. «Уральский банк реконструкции и развития»" -#. module: client_contracts -#: model:ir.actions.act_window,name:client_contracts.res_partner_contract_field_action -msgid "res.partner.contract.field.action" -msgstr "res.partner.contract.field.action" - #. module: client_contracts #: model:ir.model,name:client_contracts.model_res_partner_contract_wizard msgid "res.partner.contract.wizard" msgstr "res.partner.contract.wizard" #. module: client_contracts -#: model:ir.actions.act_window,name:client_contracts.res_partner_document_template_action -msgid "res.partner.document.template.action" -msgstr "res.partner.document.template.action" - -#. module: client_contracts -#: code:addons/client_contracts/models/res_partner_contract_annex.py:80 +#: code:addons/client_contracts/models/res_partner_contract_annex.py:64 #, python-format msgid "{name} from {date}" msgstr "{name} от {date}" diff --git a/models/res_partner_contract.py b/models/res_partner_contract.py index 144d39a..db95c18 100644 --- a/models/res_partner_contract.py +++ b/models/res_partner_contract.py @@ -1,7 +1,6 @@ import datetime from odoo import _, api, fields, models -from odoo.tools.misc import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT from ..utils import MODULE_NAME from ..utils.misc import Extension, IDocument @@ -110,7 +109,11 @@ class PartnerContract(models.Model, IDocument, Extension): def get_filename_by_document_template(self, document_template_id): return _("{type} {number} from {date}").format( - type=_(dict(document_template_id._fields['document_type'].selection).get(document_template_id.document_type)), + type=_( + dict(document_template_id._fields["document_type"].selection).get( + document_template_id.document_type + ) + ), number=self.name, date=self.get_date().strftime("%d.%m.%Y"), ) @@ -123,10 +126,9 @@ class PartnerContract(models.Model, IDocument, Extension): """ date = self.date_conclusion_fix or self.date_conclusion if date: - date = datetime.datetime.strptime(date, DEFAULT_SERVER_DATE_FORMAT) + date = self.parse_odoo_date(date) else: - date = self.create_date - date = datetime.datetime.strptime(date, DEFAULT_SERVER_DATETIME_FORMAT) + date = self.parse_odoo_datetime(self.create_date) return date def _(self, arg): diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index de2fecb..cbafbf7 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -17,24 +17,26 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): contract_id = fields.Many2one( "res.partner.contract", string="Contract", readonly=True, ) - partner_id = fields.Many2one(related="contract_id.partner_id") + company_id = fields.Many2one("res.partner", related="contract_id.company_id",) + partner_id = fields.Many2one("res.partner", related="contract_id.partner_id",) order_id = fields.Many2one( "sale.order", string="Order", - required=True, help="Orders with this partner which are not uses in annexes yet", + required=True, ) date_conclusion = fields.Date( string="Conclusion Date", default=fields.Date.today(), ) - number = fields.Integer(string="№",help="Counter of Contract Annexes") + counter = fields.Integer(string="№", help="Counter of Contract Annexes",) + currency_id = fields.Many2one(related="company_id.currency_id", readonly=True,) development_period = fields.Integer("Product Development Period (days)",) - design_cost = fields.Float(string="Design Cost",) + design_cost = fields.Monetary(string="Design Cost",) design_doc_period = fields.Integer(string="Documentation Design Period (days)",) - design_doc_cost = fields.Float(string="Documentation Design Cost",) + design_doc_cost = fields.Monetary(string="Documentation Design Cost",) delivery_address = fields.Char(string="Delivery Address",) delivery_period = fields.Integer(string="Delivery Period (days)") @@ -43,12 +45,41 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): installation_period = fields.Integer(string="Installation Period (days)",) installation_cost = fields.Integer(string="Installation Cost",) - total_cost = fields.Float(string="Total Cost",) + total_cost = fields.Monetary(string="Total Cost",) payment_part_one = fields.Float(string="Payment 1 Part (%)", default=100) payment_part_two = fields.Float(string="Payment 2 Part (%)",) payment_part_three = fields.Float(string="Payment 3 Part (%)",) + @api.multi + @api.depends("name") + def _compute_display_name(self): + for record in self: + record.display_name = "№{} {}".format( + record.counter or record.contract_id.contract_annex_number, record.name + ) + + @api.depends("specification_name", "contract_id", "order_id") + def _compute_specification_name(self): + self.specification_name = _("{name} from {date}").format( + name="{}-{}".format(self.contract_id.name, self.order_id.name), + date=self.contract_id.get_date().strftime("%d.%m.%Y"), + ) + + @api.onchange("order_id") + def _domain_order_id(self): + """Using domain function because of + simple domain does not working properly because of + contract_id is still False""" + return { + "domain": { + "order_id": [ + ("partner_id", "=", self.contract_id.partner_id.id), + ("contract_annex_id", "=", False), + ] + } + } + @api.onchange("order_id") def _onchange_order_id(self): contract_number = self.contract_id.name @@ -58,30 +89,6 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): contract=contract_number, order=order_number, ) - # Compute domain for order_id because of bug with - # not working correctly domain in model - return { - "domain": { - "order_id": [ - ("partner_id", "=", self.contract_id.partner_id.id), - ("contract_annex_id", "=", False), - ] - } - } - - @api.multi - @api.depends('name') - def _compute_display_name(self): - for record in self: - record.display_name = "№{} {}".format(record.number or record.contract_id.contract_annex_number, record.name) - - @api.depends('specification_name', 'contract_id', 'order_id') - def _compute_specification_name(self): - self.specification_name = _("{name} from {date}").format( - name="{}-{}".format(self.contract_id.name, self.order_id.name), - date=self.contract_id.get_date().strftime("%d.%m.%Y"), - ) - @api.model def create(self, values): record = super().create(values) @@ -90,8 +97,8 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): record.order_id.contract_annex_id = record.id # Counter - record.number = record.contract_id.contract_annex_number - record.contract_id.contract_annex_number += 1 + record.counter = record.contract_id.contract_annex_number + record.contract_id.contract_annex_number += 1 # TODO: should I use a sequence? return record @@ -111,30 +118,41 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): } def get_name_by_document_template(self, document_template_id): - return { - "specification": "{number} {name}", - "approval_list": "{number}.1 {name}-1", - "act_at": "{number}.2 {name}-2", - "act_ad": "{number}.3 {name}-3", - }.get(document_template_id.document_type_name, "Unknown").format( - number=self.number, - name=self.name, + return ( + { + "specification": "{counter} {name}", + "approval_list": "{counter}.1 {name}-1", + "act_at": "{counter}.2 {name}-2", + "act_ad": "{counter}.3 {name}-3", + } + .get(document_template_id.document_type_name, "Unknown") + .format(counter=self.counter, name=self.name,) ) def get_filename_by_document_template(self, document_template_id): return "{type} №{name}".format( - type=_(dict(document_template_id._fields['document_type'].selection).get(document_template_id.document_type)), + type=_( + dict(document_template_id._fields["document_type"].selection).get( + document_template_id.document_type + ) + ), name={ - "bill": "{number} {type} {name}", - "specification": "{number} {type} {name}", - "approval_list": "{number}.1 {type} {name}-1", - "act_at": "{number}.2 {type} {name}-2", - "act_ad": "{number}.3 {type} {name}-3", - }.get(document_template_id.document_type_name).format( - number=self.number, - type=_(dict(document_template_id._fields['document_type_name'].selection).get(document_template_id.document_type_name)), + "bill": "{counter} {type} {name}", + "specification": "{counter} {type} {name}", + "approval_list": "{counter}.1 {type} {name}-1", + "act_at": "{counter}.2 {type} {name}-2", + "act_ad": "{counter}.3 {type} {name}-3", + } + .get(document_template_id.document_type_name) + .format( + counter=self.counter, + type=_( + dict( + document_template_id._fields["document_type_name"].selection + ).get(document_template_id.document_type_name) + ), name=self.name, - ) + ), ) def modf(self, arg): diff --git a/models/res_partner_document_template.py b/models/res_partner_document_template.py index e3f1aea..16d1c6d 100644 --- a/models/res_partner_document_template.py +++ b/models/res_partner_document_template.py @@ -4,11 +4,14 @@ from odoo import _, fields, models class DocumentTemplate(models.Model): _name = "res.partner.document.template" _description = "Document Template" - _order = "template_type desc,company_type,sequence" + _order = "company_type,document_type,sequence" name = fields.Char() attachment_id = fields.Many2one( - "ir.attachment", string="Template Attachment", ondelete="cascade", required=True, + "ir.attachment", + string="Template Attachment", + ondelete="cascade", + required=True, ) document_type = fields.Selection( string="Type of document", @@ -16,7 +19,7 @@ class DocumentTemplate(models.Model): ("contract", _("Contract")), ("annex", _("Annex")), ("addition", _("Addition")), - ] + ], ) document_type_name = fields.Selection( string="Document", @@ -26,7 +29,7 @@ class DocumentTemplate(models.Model): ("approval_list", _("Approval List")), ("act_at", _("Act of Acceptance and Transfer")), ("act_ad", _("Act of Acceptance and Delivery")), - ] + ], ) company_type = fields.Selection( selection=[ diff --git a/utils/misc.py b/utils/misc.py index d9c3c74..9050bf8 100644 --- a/utils/misc.py +++ b/utils/misc.py @@ -1,22 +1,26 @@ -import inspect import datetime as dt +import inspect from odoo import fields -from odoo.tools.misc import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT +from odoo.tools.misc import (DEFAULT_SERVER_DATE_FORMAT, + DEFAULT_SERVER_DATETIME_FORMAT) class IDocument(object): """Class must be used as an interface for create new document based model""" def get_name_by_document_template(self, document_template_id: fields.Many2one): - raise NotImplementedError('Method {} is not implemented'.format(inspect.currentframe().f_code.co_name)) + raise NotImplementedError( + "Method {} is not implemented".format(inspect.currentframe().f_code.co_name) + ) def get_filename_by_document_template(self, document_template_id: fields.Many2one): - raise NotImplementedError('Method {} is not implemented'.format(inspect.currentframe().f_code.co_name)) + raise NotImplementedError( + "Method {} is not implemented".format(inspect.currentframe().f_code.co_name) + ) class Extension(object): - def parse_odoo_date(self, date: str): return dt.datetime.strptime(date, DEFAULT_SERVER_DATE_FORMAT) diff --git a/views/res_partner.xml b/views/res_partner.xml index fa0fb71..fb950f1 100644 --- a/views/res_partner.xml +++ b/views/res_partner.xml @@ -3,7 +3,7 @@ - res.partner.contract.field.action + Contract Fields ir.actions.act_window res.partner.contract.field tree,form @@ -12,7 +12,7 @@ - res.partner.document.template.action + Document Templates ir.actions.act_window res.partner.document.template tree,form @@ -87,7 +87,7 @@ parent="res_partner_menu_contracts" sequence="1"/> - + diff --git a/views/res_partner_contract_field.xml b/views/res_partner_contract_field.xml new file mode 100644 index 0000000..ab4059b --- /dev/null +++ b/views/res_partner_contract_field.xml @@ -0,0 +1,20 @@ + + + + + + + res.partner.contract.field.view.tree + res.partner.contract.field + + + + + + + + + + + + diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 5c65c0f..ba94e6d 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -1,5 +1,4 @@ import base64 -import logging from odoo import api, fields, models from odoo.exceptions import ValidationError @@ -7,35 +6,32 @@ from odoo.exceptions import ValidationError from ..utils import MODULE_NAME from ..utils.docxtpl import get_document_from_values_stream -_logger = logging.getLogger(__name__) - class ContractWizard(models.TransientModel): _name = "res.partner.contract.wizard" - def _get_default_partner(self): - current_id = self.env.context.get("active_id") - partner_id = self.env[self.active_model].browse(current_id).partner_id - return partner_id + def _default_target(self): + return "{model},{target_id}".format( + model=self.active_model, target_id=int(self.env.context.get("self_id")) + ) - def _get_default_template(self): - partner_id = self._get_default_partner() + def _default_document_template(self): + return self.env["res.partner.document.template"].search(self._get_template_domain(), limit=1) + + def _get_template_domain(self): template_type = { "res.partner.contract": "contract", "res.partner.contract.annex": "annex", }.get(self.active_model, False) company_type = ( - partner_id.company_form if partner_id.is_company else "person" + self.partner_id.company_form if self.partner_id.is_company else "person" ) document_template_domain = [ ("template_type", "=", template_type), ("company_type", "=", company_type), ] - - return self.env["res.partner.document.template"].search( - document_template_domain, limit=1 - ) + return document_template_domain target = fields.Reference( selection=[ @@ -43,13 +39,23 @@ class ContractWizard(models.TransientModel): ("res.partner.contract.annex", "Contract Annex"), ], string="Target", + default=_default_target, + ) + company_id = fields.Many2one( + "res.partner", string="Company", compute="_compute_company_id", + ) + partner_id = fields.Many2one( + "res.partner", string="Partner", compute="_compute_partner_id", + ) + document_name = fields.Char( + string="Document Name", compute="_compute_document_name" ) - company_id = fields.Many2one("res.partner", string="Company") - partner_id = fields.Many2one("res.partner", string="Partner", default=_get_default_partner) document_template = fields.Many2one( - "res.partner.document.template", string="Document Template", default=_get_default_template, + "res.partner.document.template", + string="Document Template", + default=_default_document_template, + readonly=False, ) - document_name = fields.Char(string="Document Name", compute='_compute_document_name') transient_field_ids = fields.One2many( "res.partner.contract.field.transient", "_contract_wizard_id", @@ -59,14 +65,34 @@ class ContractWizard(models.TransientModel): "res.partner.contract.field.transient", "_contract_wizard_id", ) + @api.depends("company_id", "target") + def _compute_company_id(self): + if self.target: + self.company_id = self.target.company_id + + @api.depends("partner_id", "target") + def _compute_partner_id(self): + if self.target: + self.partner_id = self.target.partner_id + + @api.depends("document_name", "document_template", "target") + def _compute_document_name(self): + self.document_name = self.target.get_name_by_document_template( + self.document_template + ) + @api.constrains("document_template") def _check_document_template(self): if not self.document_template: raise ValidationError("You did not set up the template...") - @api.depends('document_name', 'document_template', 'target') - def _compute_document_name(self): - self.document_name = self.target.get_name_by_document_template(self.document_template) + @api.onchange('document_template') + def _domain_document_template(self): + return { + "domain": { + "document_template": self._get_template_domain(), + } + } @api.onchange("document_template") def _onchange_document_template(self): @@ -79,25 +105,6 @@ class ContractWizard(models.TransientModel): [("technical_name", "=", technical_name),] ) - # A record is the model called from (manually set with context) - self.target = "{model},{target_id}".format( - model=self.active_model, target_id=int(self.env.context.get("self_id")) - ) - - # Check for model and get this meta fields - company_id = ( - self.target.company_id - if hasattr(self.target, "company_id") - else self.target.contract_id.company_id - ) - partner_id = ( - self.target.partner_id - if hasattr(self.target, "partner_id") - else self.target.contract_id.partner_id - ) - self.company_id = company_id - self.partner_id = partner_id - model_to_action = { "res.partner.contract": "action_get_contract_context", "res.partner.contract.annex": "action_get_annex_context", @@ -134,41 +141,19 @@ class ContractWizard(models.TransientModel): self.transient_field_ids - self.transient_field_ids_hidden ) - # TODO: remove replicate of code - template_type = { - "res.partner.contract": "contract", - "res.partner.contract.annex": "annex", - }.get(self.active_model, False) - company_type = ( - self.partner_id.company_form if self.partner_id.is_company else "person" - ) - - return {"domain": {"document_template": [("template_type", "=", template_type),("company_type", "=", company_type),],}} + # Other @api.multi def get_docx_contract(self): template = self.document_template.attachment_id + template_path = template._full_path(template.store_fname) - path_to_template = template._full_path(template.store_fname) - - fields = { - transient_field.technical_name: transient_field.value - for transient_field in ( - self.transient_field_ids + self.transient_field_ids_hidden - ) - if transient_field.technical_name and transient_field.value - } - if self.target._name == "res.partner.contract.annex": - fields.update({ - "annex_name": self.document_name, - "specification_name": self.target.specification_name, - }) - - binary_data = get_document_from_values_stream(path_to_template, fields).read() + payload = self.payload() + binary_data = get_document_from_values_stream(template_path, payload).read() encoded_data = base64.b64encode(binary_data) - attachment_name = self.target.get_filename_by_document_template(self.document_template) or "Unknown" - attachment_name = "{}.docx".format(attachment_name) + get_fn = self.target.get_filename_by_document_template + attachment_name = "{}.docx".format(get_fn(self.document_template or "Unknown")) document_as_attachment = self.env["ir.attachment"].create( { @@ -179,7 +164,51 @@ class ContractWizard(models.TransientModel): } ) - # Send message with attachment to a mail.thread of the company + return self.afterload(document_as_attachment) + + def payload(self): + # Collect fields into a key-value structure + fields = { + transient_field.technical_name: transient_field.value + for transient_field in ( + self.transient_field_ids + self.transient_field_ids_hidden + ) + if transient_field.technical_name and transient_field.value + } + # Extend with special case + if self.target._name == "res.partner.contract.annex": + fields.update( + { + "annex_name": self.document_name, + "specification_name": self.target.specification_name, + } + ) + # Extend with order product lines + if hasattr(self.target, "order_id") and self.target.order_id.order_line: + def number_generator(n=1): + while (True): + yield n + n += 1 + + counter = number_generator() + + fields.update( + { + "order_products": [ + { + "number": next(counter), + "label": item.product_id.name, + "count": item.product_uom_qty, + "unit": item.product_uom.name, + "cost": item.price_unit, + "amount": item.price_subtotal, + } for item in self.target.order_id.order_line or [] + ] + } + ) + return fields + + def afterload(self, result): res_id = self.target.id if hasattr(self.target, "contract_id"): res_id = self.target.contract_id.id @@ -189,11 +218,11 @@ class ContractWizard(models.TransientModel): "model": "res.partner.contract", "res_id": res_id, "message_type": "comment", - "attachment_ids": [(4, document_as_attachment.id, False)], + "attachment_ids": [(4, result.id, False)], } ) - return document_as_attachment + return result @property def active_model(self):