From 5b4c0b2876dc52b2c25d5e30b124ba3fb150eee8 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 18:48:12 +0500 Subject: [PATCH 01/22] [STYLE] black --- models/res_partner_contract.py | 6 +++- models/res_partner_contract_annex.py | 45 ++++++++++++++--------- models/res_partner_document_template.py | 9 +++-- utils/misc.py | 9 +++-- wizard/res_partner_contract_wizard.py | 48 +++++++++++++++++-------- 5 files changed, 79 insertions(+), 38 deletions(-) diff --git a/models/res_partner_contract.py b/models/res_partner_contract.py index 144d39a..47aa242 100644 --- a/models/res_partner_contract.py +++ b/models/res_partner_contract.py @@ -110,7 +110,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"), ) diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index de2fecb..493a418 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -27,7 +27,7 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): date_conclusion = fields.Date( string="Conclusion Date", default=fields.Date.today(), ) - number = fields.Integer(string="№",help="Counter of Contract Annexes") + number = fields.Integer(string="№", help="Counter of Contract Annexes") development_period = fields.Integer("Product Development Period (days)",) @@ -70,12 +70,14 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): } @api.multi - @api.depends('name') + @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) + record.display_name = "№{} {}".format( + record.number or record.contract_id.contract_annex_number, record.name + ) - @api.depends('specification_name', 'contract_id', 'order_id') + @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), @@ -111,30 +113,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": "{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,) ) 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( + } + .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)), + 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..7de7d06 100644 --- a/models/res_partner_document_template.py +++ b/models/res_partner_document_template.py @@ -8,7 +8,10 @@ class DocumentTemplate(models.Model): 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..d4b53c9 100644 --- a/utils/misc.py +++ b/utils/misc.py @@ -9,14 +9,17 @@ 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/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 5c65c0f..9cca02d 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -24,9 +24,7 @@ class ContractWizard(models.TransientModel): "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" - ) + company_type = partner_id.company_form if partner_id.is_company else "person" document_template_domain = [ ("template_type", "=", template_type), @@ -45,11 +43,17 @@ class ContractWizard(models.TransientModel): string="Target", ) 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, + 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, + ) + document_name = fields.Char( + string="Document Name", compute="_compute_document_name" ) - document_name = fields.Char(string="Document Name", compute='_compute_document_name') transient_field_ids = fields.One2many( "res.partner.contract.field.transient", "_contract_wizard_id", @@ -64,9 +68,11 @@ class ContractWizard(models.TransientModel): if not self.document_template: raise ValidationError("You did not set up the template...") - @api.depends('document_name', 'document_template', 'target') + @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) + self.document_name = self.target.get_name_by_document_template( + self.document_template + ) @api.onchange("document_template") def _onchange_document_template(self): @@ -143,7 +149,14 @@ class ContractWizard(models.TransientModel): 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),],}} + return { + "domain": { + "document_template": [ + ("template_type", "=", template_type), + ("company_type", "=", company_type), + ], + } + } @api.multi def get_docx_contract(self): @@ -159,15 +172,20 @@ class ContractWizard(models.TransientModel): 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, - }) + 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() encoded_data = base64.b64encode(binary_data) - attachment_name = self.target.get_filename_by_document_template(self.document_template) or "Unknown" + attachment_name = ( + self.target.get_filename_by_document_template(self.document_template) + or "Unknown" + ) attachment_name = "{}.docx".format(attachment_name) document_as_attachment = self.env["ir.attachment"].create( From f12ac74014cc00f07ffd83af3bbd36dc5a95e2ef Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 18:50:17 +0500 Subject: [PATCH 02/22] [IMP] rename annex number to counter --- data/fields_default.xml | 2 +- models/res_partner_contract_annex.py | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/data/fields_default.xml b/data/fields_default.xml index 9703259..55a7c56 100644 --- a/data/fields_default.xml +++ b/data/fields_default.xml @@ -187,7 +187,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/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index 493a418..76d68ff 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -27,7 +27,7 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): 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") development_period = fields.Integer("Product Development Period (days)",) @@ -74,7 +74,7 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): def _compute_display_name(self): for record in self: record.display_name = "№{} {}".format( - record.number or record.contract_id.contract_annex_number, record.name + record.counter or record.contract_id.contract_annex_number, record.name ) @api.depends("specification_name", "contract_id", "order_id") @@ -92,7 +92,7 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): record.order_id.contract_annex_id = record.id # Counter - record.number = record.contract_id.contract_annex_number + record.counter = record.contract_id.contract_annex_number record.contract_id.contract_annex_number += 1 return record @@ -115,13 +115,13 @@ 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", + "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(number=self.number, name=self.name,) + .format(counter=self.counter, name=self.name,) ) def get_filename_by_document_template(self, document_template_id): @@ -132,15 +132,15 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): ) ), 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", + "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( - number=self.number, + counter=self.counter, type=_( dict( document_template_id._fields["document_type_name"].selection From 405884ba9eefbd06eea9bdefc59d509f4851b4ee Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 19:03:22 +0500 Subject: [PATCH 03/22] [IMP] compute partner_id and company_id in annex model --- data/fields_default.xml | 4 +-- models/res_partner_contract_annex.py | 3 ++- wizard/res_partner_contract_wizard.py | 38 +++++++++------------------ 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/data/fields_default.xml b/data/fields_default.xml index 55a7c56..98fe889 100644 --- a/data/fields_default.xml +++ b/data/fields_default.xml @@ -151,8 +151,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 "") diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index 76d68ff..cc77722 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -17,7 +17,8 @@ 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", diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 9cca02d..b97c330 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -13,18 +13,12 @@ _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 _get_default_template(self): - partner_id = self._get_default_partner() 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" + company_type = self.partner_id.company_form if self.partner_id.is_company else "person" document_template_domain = [ ("template_type", "=", template_type), @@ -42,10 +36,8 @@ class ContractWizard(models.TransientModel): ], string="Target", ) - company_id = fields.Many2one("res.partner", string="Company") - partner_id = fields.Many2one( - "res.partner", string="Partner", default=_get_default_partner - ) + 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_template = fields.Many2one( "res.partner.document.template", string="Document Template", @@ -68,6 +60,16 @@ class ContractWizard(models.TransientModel): if not self.document_template: raise ValidationError("You did not set up the template...") + @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( @@ -90,20 +92,6 @@ class ContractWizard(models.TransientModel): 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", From fa2ab72213ddfb64229b0faa6938cde31cc708b5 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 19:07:11 +0500 Subject: [PATCH 04/22] [ADD] currency_id, Float->Monetary type --- models/res_partner_contract_annex.py | 9 +++++---- views/res_partner_contract_annex.xml | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index cc77722..a7e1b9a 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -28,14 +28,15 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): date_conclusion = fields.Date( string="Conclusion Date", default=fields.Date.today(), ) - counter = 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)") @@ -44,7 +45,7 @@ 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 (%)",) diff --git a/views/res_partner_contract_annex.xml b/views/res_partner_contract_annex.xml index 2d10a09..48c76a3 100644 --- a/views/res_partner_contract_annex.xml +++ b/views/res_partner_contract_annex.xml @@ -12,6 +12,7 @@ + From 0f6d44e8090b5c00b379ae5080b02acf211041ec Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 19:29:31 +0500 Subject: [PATCH 05/22] [IMP] order id domain --- models/res_partner_contract_annex.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index a7e1b9a..f6ac22a 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -22,8 +22,8 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): 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(), @@ -60,8 +60,11 @@ 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 + @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": [ From 1c661dbd7babc4bb32c38c65ffe9537d441246d3 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 19:33:54 +0500 Subject: [PATCH 06/22] [ADD] comment --- models/res_partner_contract_annex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index f6ac22a..1372853 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -98,7 +98,7 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): # Counter record.counter = record.contract_id.contract_annex_number - record.contract_id.contract_annex_number += 1 + record.contract_id.contract_annex_number += 1 # TODO: should I use a sequence? return record From 021d0ab997e681e8dd722baa5267cb762ba5ae4a Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 19:34:25 +0500 Subject: [PATCH 07/22] [STYLE] black --- wizard/res_partner_contract_wizard.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index b97c330..70101a2 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,8 +6,6 @@ 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" @@ -18,7 +15,9 @@ class ContractWizard(models.TransientModel): "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" + company_type = ( + self.partner_id.company_form if self.partner_id.is_company else "person" + ) document_template_domain = [ ("template_type", "=", template_type), @@ -36,8 +35,12 @@ class ContractWizard(models.TransientModel): ], string="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",) + 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_template = fields.Many2one( "res.partner.document.template", string="Document Template", From b39cfe2a63eced736e1cb32f8587b0a7c211a346 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 20 Jan 2020 20:08:21 +0500 Subject: [PATCH 08/22] [IMP] target is default field, document_template is init-compute field --- wizard/res_partner_contract_wizard.py | 74 ++++++++++++--------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 70101a2..82cf5f0 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -10,22 +10,9 @@ from ..utils.docxtpl import get_document_from_values_stream class ContractWizard(models.TransientModel): _name = "res.partner.contract.wizard" - def _get_default_template(self): - 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" - ) - - document_template_domain = [ - ("template_type", "=", template_type), - ("company_type", "=", company_type), - ] - - return self.env["res.partner.document.template"].search( - document_template_domain, limit=1 + def _default_target(self): + return "{model},{target_id}".format( + model=self.active_model, target_id=int(self.env.context.get("self_id")) ) target = fields.Reference( @@ -34,6 +21,7 @@ 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", @@ -44,7 +32,8 @@ class ContractWizard(models.TransientModel): document_template = fields.Many2one( "res.partner.document.template", string="Document Template", - default=_get_default_template, + compute="_compute_document_template", + readonly=False, ) document_name = fields.Char( string="Document Name", compute="_compute_document_name" @@ -79,6 +68,34 @@ class ContractWizard(models.TransientModel): self.document_template ) + @api.depends('target') + def _compute_document_template(self): + self.document_template = self.env["res.partner.document.template"].search(self._get_template_domain(), limit=1) + + @api.onchange('document_template') + def _domain_document_template(self): + return { + "domain": { + "document_template": self._get_template_domain(), + } + } + + def _get_template_domain(self): + template_type = { + "res.partner.contract": "contract", + "res.partner.contract.annex": "annex", + }.get(self.active_model, False) + company_type = { + True: self.partner_id.company_form, + False: "person", + }.get(self.partner_id.is_company, False) + + document_template_domain = [ + ("template_type", "=", template_type), + ("company_type", "=", company_type), + ] + return document_template_domain + @api.onchange("document_template") def _onchange_document_template(self): """Creates transient fields for generate contract template @@ -90,11 +107,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")) - ) - model_to_action = { "res.partner.contract": "action_get_contract_context", "res.partner.contract.annex": "action_get_annex_context", @@ -131,24 +143,6 @@ 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), - ], - } - } - @api.multi def get_docx_contract(self): template = self.document_template.attachment_id From cabd775c7958016a02aeec06ee2d30506dbc0896 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Tue, 21 Jan 2020 16:00:38 +0500 Subject: [PATCH 09/22] [IMP] review code change: company_type dict to ternary operator --- wizard/res_partner_contract_wizard.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 82cf5f0..3a499fe 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -85,10 +85,9 @@ class ContractWizard(models.TransientModel): "res.partner.contract": "contract", "res.partner.contract.annex": "annex", }.get(self.active_model, False) - company_type = { - True: self.partner_id.company_form, - False: "person", - }.get(self.partner_id.is_company, False) + company_type = ( + self.partner_id.company_form if self.partner_id.is_company else "person" + ) document_template_domain = [ ("template_type", "=", template_type), From 99cdb48a7c97c58784d9c7df34e9b16ec31f16e7 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Tue, 21 Jan 2020 16:07:57 +0500 Subject: [PATCH 10/22] [STYLE] order of methods --- models/res_partner_contract_annex.py | 36 ++++++++++---------- wizard/res_partner_contract_wizard.py | 48 ++++++++++++++------------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index 1372853..cbafbf7 100644 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -51,13 +51,19 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): payment_part_two = fields.Float(string="Payment 2 Part (%)",) payment_part_three = fields.Float(string="Payment 3 Part (%)",) - @api.onchange("order_id") - def _onchange_order_id(self): - contract_number = self.contract_id.name - order_number = self.order_id.name or "SO###" + @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 + ) - self.name = "{contract}-{order}".format( - contract=contract_number, order=order_number, + @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") @@ -74,19 +80,13 @@ class ContractOrderAnnex(models.Model, IDocument, Extension): } } - @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.onchange("order_id") + def _onchange_order_id(self): + contract_number = self.contract_id.name + order_number = self.order_id.name or "SO###" - @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"), + self.name = "{contract}-{order}".format( + contract=contract_number, order=order_number, ) @api.model diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 3a499fe..8bf7150 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -29,15 +29,15 @@ class ContractWizard(models.TransientModel): partner_id = fields.Many2one( "res.partner", string="Partner", compute="_compute_partner_id", ) + document_name = fields.Char( + string="Document Name", compute="_compute_document_name" + ) document_template = fields.Many2one( "res.partner.document.template", string="Document Template", compute="_compute_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", @@ -47,11 +47,6 @@ class ContractWizard(models.TransientModel): "res.partner.contract.field.transient", "_contract_wizard_id", ) - @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("company_id", "target") def _compute_company_id(self): if self.target: @@ -72,6 +67,11 @@ class ContractWizard(models.TransientModel): def _compute_document_template(self): self.document_template = self.env["res.partner.document.template"].search(self._get_template_domain(), limit=1) + @api.constrains("document_template") + def _check_document_template(self): + if not self.document_template: + raise ValidationError("You did not set up the template...") + @api.onchange('document_template') def _domain_document_template(self): return { @@ -80,21 +80,6 @@ class ContractWizard(models.TransientModel): } } - def _get_template_domain(self): - 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" - ) - - document_template_domain = [ - ("template_type", "=", template_type), - ("company_type", "=", company_type), - ] - return document_template_domain - @api.onchange("document_template") def _onchange_document_template(self): """Creates transient fields for generate contract template @@ -142,6 +127,8 @@ class ContractWizard(models.TransientModel): self.transient_field_ids - self.transient_field_ids_hidden ) + # Other + @api.multi def get_docx_contract(self): template = self.document_template.attachment_id @@ -197,6 +184,21 @@ class ContractWizard(models.TransientModel): return document_as_attachment + def _get_template_domain(self): + 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" + ) + + document_template_domain = [ + ("template_type", "=", template_type), + ("company_type", "=", company_type), + ] + return document_template_domain + @property def active_model(self): return self.env.context.get("active_model") From cb29bd21277b6cba0298549fa4e29a7ca887894b Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Tue, 21 Jan 2020 19:52:33 +0500 Subject: [PATCH 11/22] [ADD] todolist --- TODOLIST.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 TODOLIST.md diff --git a/TODOLIST.md b/TODOLIST.md new file mode 100644 index 0000000..9629d66 --- /dev/null +++ b/TODOLIST.md @@ -0,0 +1,13 @@ +# TODO LIST + +## Features + - Add name to `document_template` and `contract_field` actions + - Add to tree view of `res.partner.contract.field` fields: `name`, `description`, `technical_name`, `visible` + - Change order of `res.partner.document.template` to order by `company_type, document_type, sequence` + +## Fixes + - Change all `parents` to `genitive` + - Merge `document_type` and `template_type` in `res.partner.document.template` + +## Big feature + - Separate XML actions that generates transient fields for all types of documents From dbceef40429c66864f20c22f5f120d5798086a22 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Wed, 22 Jan 2020 16:15:03 +0500 Subject: [PATCH 12/22] [ADD] name to actions --- TODOLIST.md | 2 +- i18n/ru.po | 53 ++++++++++++++++++++++++------------------- views/res_partner.xml | 4 ++-- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/TODOLIST.md b/TODOLIST.md index 9629d66..2c07eda 100644 --- a/TODOLIST.md +++ b/TODOLIST.md @@ -1,7 +1,7 @@ # TODO LIST ## Features - - Add name to `document_template` and `contract_field` actions + + Add name to `document_template` and `contract_field` actions; - Add to tree view of `res.partner.contract.field` fields: `name`, `description`, `technical_name`, `visible` - Change order of `res.partner.document.template` to order by `company_type, document_type, sequence` diff --git a/i18n/ru.po b/i18n/ru.po index 4356772..c345b8d 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" @@ -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/views/res_partner.xml b/views/res_partner.xml index fa0fb71..759344b 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 From c356cae37a951d3183f9946c8bd4da69045bfcc5 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Wed, 22 Jan 2020 16:31:59 +0500 Subject: [PATCH 13/22] [ADD] contract field tree view --- TODOLIST.md | 2 +- __manifest__.py | 1 + views/res_partner_contract_field.xml | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 views/res_partner_contract_field.xml diff --git a/TODOLIST.md b/TODOLIST.md index 2c07eda..8300284 100644 --- a/TODOLIST.md +++ b/TODOLIST.md @@ -2,7 +2,7 @@ ## Features + Add name to `document_template` and `contract_field` actions; - - Add to tree view of `res.partner.contract.field` fields: `name`, `description`, `technical_name`, `visible` + + Add to tree view of `res.partner.contract.field` fields: `name`, `description`, `technical_name`, `visible` - Change order of `res.partner.document.template` to order by `company_type, document_type, sequence` ## Fixes 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/views/res_partner_contract_field.xml b/views/res_partner_contract_field.xml new file mode 100644 index 0000000..041b025 --- /dev/null +++ b/views/res_partner_contract_field.xml @@ -0,0 +1,20 @@ + + + + + + + res.partner.contract.field.view.tree + res.partner.contract.field + + + + + + + + + + + + \ No newline at end of file From 8616c789326a6cb505fda319cf3bf9381b2e9853 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Wed, 22 Jan 2020 16:35:49 +0500 Subject: [PATCH 14/22] [IMP] changed order --- models/res_partner_document_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/res_partner_document_template.py b/models/res_partner_document_template.py index 7de7d06..16d1c6d 100644 --- a/models/res_partner_document_template.py +++ b/models/res_partner_document_template.py @@ -4,7 +4,7 @@ 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( From 60862898fcc420edc56c184d69c5e0ee5fd9ea39 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Wed, 22 Jan 2020 16:35:59 +0500 Subject: [PATCH 15/22] [ADD] todo --- TODOLIST.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODOLIST.md b/TODOLIST.md index 8300284..e4e153f 100644 --- a/TODOLIST.md +++ b/TODOLIST.md @@ -8,6 +8,7 @@ ## 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 From e15bdae70a3bebf7e81ded3e5a07baac2b43f832 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Wed, 22 Jan 2020 16:37:00 +0500 Subject: [PATCH 16/22] [IMP] todo --- TODOLIST.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/TODOLIST.md b/TODOLIST.md index e4e153f..01f3874 100644 --- a/TODOLIST.md +++ b/TODOLIST.md @@ -1,9 +1,6 @@ # TODO LIST ## Features - + Add name to `document_template` and `contract_field` actions; - + Add to tree view of `res.partner.contract.field` fields: `name`, `description`, `technical_name`, `visible` - - Change order of `res.partner.document.template` to order by `company_type, document_type, sequence` ## Fixes - Change all `parents` to `genitive` From 027736de8a262aa3cd8d434f89c41c9bcfcaff2a Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Wed, 22 Jan 2020 16:46:56 +0500 Subject: [PATCH 17/22] [IMP] using parse_date --- models/res_partner_contract.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/models/res_partner_contract.py b/models/res_partner_contract.py index 47aa242..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 @@ -127,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): From 2360093e24d61af92afe9c1c9dfd6f69f2902ea7 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Wed, 22 Jan 2020 17:20:43 +0500 Subject: [PATCH 18/22] [IMP] order imports --- utils/misc.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/misc.py b/utils/misc.py index d4b53c9..9050bf8 100644 --- a/utils/misc.py +++ b/utils/misc.py @@ -1,8 +1,9 @@ -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): From 94c50928ec52dbeec4c6641eba1c9ca6612cb9b6 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 27 Jan 2020 13:56:09 +0500 Subject: [PATCH 19/22] [IMP] less code --- wizard/res_partner_contract_wizard.py | 47 +++++++++++++-------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 8bf7150..b7b6d54 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -132,9 +132,27 @@ class ContractWizard(models.TransientModel): @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) + payload = self.payload() + binary_data = get_document_from_values_stream(template_path, payload).read() + encoded_data = base64.b64encode(binary_data) + 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( + { + "name": attachment_name, + "datas_fname": attachment_name, + "type": "binary", + "datas": encoded_data, + } + ) + + return self.afterload(document_as_attachment) + + def payload(self): fields = { transient_field.technical_name: transient_field.value for transient_field in ( @@ -149,41 +167,22 @@ class ContractWizard(models.TransientModel): "specification_name": self.target.specification_name, } ) + return fields - binary_data = get_document_from_values_stream(path_to_template, fields).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) - - document_as_attachment = self.env["ir.attachment"].create( - { - "name": attachment_name, - "datas_fname": attachment_name, - "type": "binary", - "datas": encoded_data, - } - ) - - # Send message with attachment to a mail.thread of the company + def afterload(self, result): res_id = self.target.id if hasattr(self.target, "contract_id"): res_id = self.target.contract_id.id - self.env["mail.message"].create( + return self.env["mail.message"].create( { "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 - def _get_template_domain(self): template_type = { "res.partner.contract": "contract", From 06864fe013fd4f304352eadd4fd3e0d27b540e4b Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 27 Jan 2020 15:12:59 +0500 Subject: [PATCH 20/22] [FIX] cant choose template --- wizard/res_partner_contract_wizard.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index b7b6d54..7affac2 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -15,6 +15,9 @@ class ContractWizard(models.TransientModel): model=self.active_model, target_id=int(self.env.context.get("self_id")) ) + def _default_document_template(self): + return self.env["res.partner.document.template"].search(self._get_template_domain(), limit=1) + target = fields.Reference( selection=[ ("res.partner.contract", "Contract"), @@ -35,7 +38,7 @@ class ContractWizard(models.TransientModel): document_template = fields.Many2one( "res.partner.document.template", string="Document Template", - compute="_compute_document_template", + default=_default_document_template, readonly=False, ) transient_field_ids = fields.One2many( @@ -63,10 +66,6 @@ class ContractWizard(models.TransientModel): self.document_template ) - @api.depends('target') - def _compute_document_template(self): - self.document_template = self.env["res.partner.document.template"].search(self._get_template_domain(), limit=1) - @api.constrains("document_template") def _check_document_template(self): if not self.document_template: From f84391ac2e32aba4dc3822f626a4515bcccea2c3 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Mon, 27 Jan 2020 15:33:03 +0500 Subject: [PATCH 21/22] [IMP] add order_line getter, better code --- wizard/res_partner_contract_wizard.py | 57 ++++++++++++++++++++------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 7affac2..ba94e6d 100644 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -18,6 +18,21 @@ class ContractWizard(models.TransientModel): 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 = ( + 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 document_template_domain + target = fields.Reference( selection=[ ("res.partner.contract", "Contract"), @@ -152,6 +167,7 @@ class ContractWizard(models.TransientModel): 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 ( @@ -159,6 +175,7 @@ class ContractWizard(models.TransientModel): ) if transient_field.technical_name and transient_field.value } + # Extend with special case if self.target._name == "res.partner.contract.annex": fields.update( { @@ -166,6 +183,29 @@ class ContractWizard(models.TransientModel): "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): @@ -173,7 +213,7 @@ class ContractWizard(models.TransientModel): if hasattr(self.target, "contract_id"): res_id = self.target.contract_id.id - return self.env["mail.message"].create( + self.env["mail.message"].create( { "model": "res.partner.contract", "res_id": res_id, @@ -182,20 +222,7 @@ class ContractWizard(models.TransientModel): } ) - def _get_template_domain(self): - 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" - ) - - document_template_domain = [ - ("template_type", "=", template_type), - ("company_type", "=", company_type), - ] - return document_template_domain + return result @property def active_model(self): From cf5e827380278b14f0aeee9fd131dbea9f2ffcc8 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Tue, 28 Jan 2020 12:35:35 +0500 Subject: [PATCH 22/22] [IMP] review fix --- i18n/ru.po | 2 +- views/res_partner.xml | 2 +- views/res_partner_contract_field.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/i18n/ru.po b/i18n/ru.po index c345b8d..9abc06a 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -1015,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 "Шаблоны" diff --git a/views/res_partner.xml b/views/res_partner.xml index 759344b..fb950f1 100644 --- a/views/res_partner.xml +++ b/views/res_partner.xml @@ -87,7 +87,7 @@ parent="res_partner_menu_contracts" sequence="1"/> - - \ No newline at end of file +