diff --git a/__manifest__.py b/__manifest__.py index 9323ed5..4995f1a 100755 --- a/__manifest__.py +++ b/__manifest__.py @@ -11,7 +11,7 @@ "category": "Invoicing & Payments", "version": "14.0.1.0.0", "depends": ["base", "contacts", "hr", "l10n_ru", "sale", "sale_margin"], - "external_dependencies": {"python": ["docxtpl"]}, + "external_dependencies": {"python": ["docxtpl", "num2words"]}, "data": [ "data/assets_extension.xml", "data/fields_default.xml", diff --git a/data/fields_default.xml b/data/fields_default.xml index 86755f6..4181c58 100755 --- a/data/fields_default.xml +++ b/data/fields_default.xml @@ -14,7 +14,7 @@ self = record # res.partner.contract partner = self.partner_id # res.partner -seller = self.company_id +seller = self.company_id.partner_id # Functions _ = self._ @@ -164,7 +164,7 @@ action = ctx # Aliases self = record # res.partner.contract.annex -seller = self.company_id +seller = self.company_id.partner_id partner = self.partner_id # Functions diff --git a/models/res_partner_contract.py b/models/res_partner_contract.py index a158e3a..6320247 100755 --- a/models/res_partner_contract.py +++ b/models/res_partner_contract.py @@ -48,9 +48,9 @@ class PartnerContract(models.Model): # , IDocument, Extension): required=True, ) company_id = fields.Many2one( - "res.partner", + "res.company", string="Company", - default=lambda self: self.env.company.partner_id, + default=lambda self: self.env.company, ) create_date_ts = fields.Char(default=_get_default_create_date_ts) res_model = fields.Char(default=lambda self: self._name) @@ -68,8 +68,8 @@ class PartnerContract(models.Model): # , IDocument, Extension): default=lambda self: self.date_conclusion, ) contract_annex_ids = fields.One2many( - "res.partner.contract.annex", - "contract_id", + comodel_name="res.partner.contract.annex", + inverse_name="contract_id", string="Annexes", help="Annexes to this contract", ) @@ -101,6 +101,7 @@ class PartnerContract(models.Model): # , IDocument, Extension): self.write({"state": "draft"}) def action_print_form(self): + self.ensure_one() view = self.env.ref( "{}.res_partner_wizard_print_document_view".format(MODULE_NAME) ) @@ -121,9 +122,11 @@ class PartnerContract(models.Model): # , IDocument, Extension): } def get_name_by_document_template(self, document_template_id): + self.ensure_one() return self.name def get_filename_by_document_template(self, document_template_id): + self.ensure_one() return _("{type} {number} from {date}").format( type=_( dict(document_template_id._fields["document_type"].selection).get( @@ -140,10 +143,12 @@ class PartnerContract(models.Model): # , IDocument, Extension): Returns: datetime.datetime -- date_conclusion_fix or date_conclusion or create_date """ + self.ensure_one() date = self.date_conclusion_fix or self.date_conclusion return date or self.create_date - def _(self, arg): + @staticmethod + def _(arg): """Uses in xml action (data/fields_default) Arguments: diff --git a/models/res_partner_contract_annex.py b/models/res_partner_contract_annex.py index 344d4b6..84c4a45 100755 --- a/models/res_partner_contract_annex.py +++ b/models/res_partner_contract_annex.py @@ -8,6 +8,7 @@ from ..utils import MODULE_NAME # from ..utils.misc import Extension, IDocument _logger = logging.getLogger(__name__) + class ContractOrderAnnex(models.Model): # , IDocument, Extension): _name = "res.partner.contract.annex" _inherit = ["client_contracts.utils"] @@ -29,17 +30,17 @@ class ContractOrderAnnex(models.Model): # , IDocument, Extension): readonly=True, ) company_id = fields.Many2one( - "res.partner", + comodel_name="res.company", related="contract_id.company_id", ) partner_id = fields.Many2one( - "res.partner", + comodel_name="res.partner", related="contract_id.partner_id", ) order_id = fields.Many2one( - "sale.order", - string="Order", - help="This partner's orders which are not used in annexes yet", + comodel_name="sale.order", + string="Sale order", + help="Sale order for this annex.", required=True, ) date_conclusion = fields.Date( @@ -51,6 +52,7 @@ class ContractOrderAnnex(models.Model): # , IDocument, Extension): help="Contract Annexes counter", ) currency_id = fields.Many2one( + comodel_name="res.currency", string="Currency", default=lambda self: self.env.company.currency_id.id, ) @@ -143,16 +145,21 @@ class ContractOrderAnnex(models.Model): # , IDocument, Extension): order=order_number, ) - @api.model - def create(self, values): - _logger.debug("\n\n Values: %s\n\n", values) - record = super(ContractOrderAnnex, self).create(values) - # Fill annex_id to domain it in future - # record.order_id.contract_annex_id = record.id - # Counter - record.counter = record.contract_id.contract_annex_number - record.contract_id.contract_annex_number += 1 # TODO: should I use a sequence? - return record + def create(self, values_list): + _logger.debug("\n\n Values: %s\n\n", values_list) + if isinstance(values_list, dict): + values_list = [values_list] + _logger.debug("\n\n Values fixed: %s\n\n", values_list) + records = super(ContractOrderAnnex, self).create(values_list) + for record in records: + # Fill annex_id to domain it in future + # record.order_id.contract_annex_id = record.id + # Counter + record.counter = record.contract_id.contract_annex_number + record.contract_id.contract_annex_number += ( + 1 # TODO: should I use a sequence? + ) + return records def action_print_form(self): view = self.env.ref( diff --git a/models/res_partner_contract_field.py b/models/res_partner_contract_field.py index 127f0df..0d8f3e3 100755 --- a/models/res_partner_contract_field.py +++ b/models/res_partner_contract_field.py @@ -13,11 +13,12 @@ class ContractField(models.Model): ) technical_name = fields.Char( string="Technical Name", - help="Name uses in template", + help="Name for using in templates", required=True, ) description = fields.Char( string="Description", + help="Description for this field to be showed in fields list in print form creation wizard.", translate=True, default="", ) @@ -26,5 +27,7 @@ class ContractField(models.Model): ) visible = fields.Boolean( string="Visible", + help="To show this field in fields list in print form creation wizard\n" + "User can change showed field's values in wizard.", default=True, ) diff --git a/models/sale_order.py b/models/sale_order.py index 3c2ea5c..ad01266 100755 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -12,25 +12,39 @@ class SaleOrder(models.Model): default=45, ) contract_annex_id = fields.Many2one( - "res.partner.contract.annex", + comodel_name="res.partner.contract.annex", string="Contract Annex", - readonly=True, + compute="get_contract_annex_id", ) + contract_annex_ids = fields.One2many( + comodel_name="res.partner.contract.annex", + inverse_name="order_id", + string="Annex for this Sale order", + help="Technical field for binding with contract annex\n" + "In form this link showed in 'contract_annex_id' field.", + ) + # Extend default field for showing payment terms created by this module only. payment_term_id = fields.Many2one( - "account.payment.term", + comodel_name="account.payment.term", domain=lambda self: [("id", "in", self._get_payment_terms())], ) def _get_payment_terms(self): - ref = self.env.ref - terms = ( - ref("{}.{}".format(MODULE_NAME, external_id)).id + terms = [ + self.env.ref("{}.{}".format(MODULE_NAME, external_id)).id for external_id in ( "payment_term_prepaid", "payment_term_postpayment", "payment_term_partial_2", "payment_term_partial_3", ) - ) - return list(terms) + ] + return terms + + @api.onchange("contract_annex_ids") + def get_contract_annex_id(self): + if self.contract_annex_ids: + self.contract_annex_id = self.contract_annex_ids[0].id + else: + self.contract_annex_id = False diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index ca472bb..9ff1cd8 100755 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,9 +1,12 @@ id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink access_contracts_contracts,access_contracts_contracts,model_res_partner_contract,base.group_user,1,1,1,1 + access_contracts_field,access_contracts_field,model_res_partner_contract_field,base.group_user,1,0,0,0 +access_contracts_field_manager,access_contracts_field,model_res_partner_contract_field,base.group_no_one,1,1,1,1 + access_contracts_field_transient,access_contracts_field_transient,model_res_partner_contract_field_transient,base.group_user,1,1,1,1 access_contracts_field_contract_annex,access_contracts_field_contract_annex,model_res_partner_contract_annex,base.group_user,1,1,1,1 access_contract_document_template,access_contract_document_template,model_res_partner_document_template,base.group_user,1,0,0,0 -access_contract_document_template_manager,access_contract_document_template,model_res_partner_document_template,hr.group_hr_manager,1,1,1,1 +access_contract_document_template_manager,access_contract_document_template,model_res_partner_document_template,base.group_no_one,1,1,1,1 access_contracts_wizard,access_contracts_wizard,model_res_partner_contract_wizard,base.group_user,1,1,1,1 diff --git a/utils/contract_context_values.py b/utils/contract_context_values.py deleted file mode 100644 index 8067ad7..0000000 --- a/utils/contract_context_values.py +++ /dev/null @@ -1,312 +0,0 @@ -# Aliases -self = record # res.partner.contract - -partner = self.partner_id # res.partner -seller = self.company_id - -# Functions -_ = self._ -get_date = self.get_date - -# Parse date -months = ["", - "января", "февраля", "марта", "апреля", - "мая", "июня", "июля", "августа", - "сентября", "октября", "ноября", "декабря", - ] -date = get_date() -dd = date.day -mm = date.month -yyyy = date.year -yy = yyyy % 100 -MM = months[mm] - -dd = dd if dd // 10 else '0{}'.format(dd) -mm = mm if mm // 10 else '0{}'.format(mm) - -# ctx keys must be decalared in this xml with id equal to "contract_field_{technical_name}" -ctx = { - "contract_number": self.name, - - "dd": dd, - "mm": mm, - "MM": MM, - "yy": yy, - "yyyy": yyyy, - - "seller_name": seller.name_write, - "seller_company_form": _(dict(seller._fields['company_form'].selection).get(seller.company_form)), - "seller_representer_name": seller.representative_id.name, - "seller_representer_name_parent": seller.representative_id.name_genitive, - "seller_representer_name_initials": seller.representative_id.name_initials, - "seller_representer_function": seller.representative_id.function, - "seller_representer_function_parent": seller.representative_id.function_genitive, - "seller_representer_document_parent": seller.representative_document, - "seller_inn": seller.vat, - "seller_kpp": seller.iec, - "seller_ogrn": seller.psrn, - "seller_business_address": seller.full_address, - "seller_phone": seller.phone, - "seller_whatsapp": seller.whatsapp, - "seller_telegram": seller.telegram, - "seller_email": seller.email, - - "partner_name": partner.name_write, - "partner_inn": partner.vat, - "partner_business_address": partner.full_address, - "partner_phone": partner.phone, - "partner_whatsapp": partner.whatsapp, - "partner_telegram": partner.telegram, - "partner_email": partner.email, -} - -seller_bank = seller.bank_ids and seller.bank_ids[0] -if seller_bank: - bank = seller_bank.bank_id - bank_name = bank and bank.name or "" - bank_city = "г. {city}".format(city=bank.city) if bank and bank.city else "" - seller_bank_name = "{} {}".format(bank_name, bank_city).strip() - - ctx.update({ - "seller_bank": seller_bank_name, - "seller_rs": seller_bank.acc_number, - "seller_ks": bank.corr_account, - "seller_bic": bank.bic, - }) - -partner_bank = partner.bank_ids and partner.bank_ids[0] -if partner_bank: - bank = partner_bank.bank_id - bank_name = bank and bank.name or "" - bank_city = "г. {city}".format(city=bank.city) if bank and bank.city else "" - partner_bank_name = "{} {}".format(bank_name, bank_city).strip() - - ctx.update({ - "partner_bank": partner_bank_name, - "partner_rs": partner_bank.acc_number, - "partner_ks": bank.corr_account, - "partner_bic": bank.bic, - }) - -# Person -if not partner.is_company: - ctx.update({ - "partner_representer_name": partner.name_write, - "partner_representer_name_initials": partner.name_initials, - "partner_representer_passport_number": partner.passport_number, - "partner_representer_passport_date": partner.passport_date, - "partner_representer_passport_department": partner.passport_department, - "partner_representer_passport_department_code": partner.passport_department_code, - }) - if not partner.name_write: - ctx.update({ - "partner_name": partner.name, - "partner_representer_name": partner.name, - }) -else: - # Company - ctx.update({ - "partner_company_form": _(dict(partner._fields['company_form'].selection).get(partner.company_form)), - "partner_representer_name": partner.representative_id.name, - "partner_representer_name_parent": partner.representative_id.name_genitive, - "partner_representer_name_initials": partner.representative_id.name_initials, - "partner_representer_function": partner.representative_id.function, - "partner_representer_function_parent": partner.representative_id.function_genitive, - "partner_representer_document_parent": partner.representative_document, - }) - - if partner.company_form == 'sp': - # Sole Proprietor - ctx.update({ - "partner_ip_number": partner.sp_register_number, - "partner_ip_date": partner.sp_register_date, - "partner_ogrnip": partner.psrn_sp, - "partner_representer_passport_number": partner.representative_id.passport_number, - "partner_representer_passport_date": partner.representative_id.passport_date, - "partner_representer_passport_department": partner.representative_id.passport_department, - "partner_representer_passport_department_code": partner.representative_id.passport_department_code, - }) - if partner.company_form == 'plc': - # Private Limited Company - ctx.update({ - "partner_kpp": partner.iec, - "partner_ogrn": partner.psrn, - }) - -action = ctx -< / field > -< / record > - -< !-- Action --> -< record -id = "action_get_annex_context" -model = "ir.actions.server" > -< field -name = "name" > Generate -Context -for Annex -< field -name = "model_id" -ref = "client_contracts.model_res_partner_contract_wizard" / > -< field -name = "binding_model_id" -ref = "client_contracts.model_res_partner_contract_wizard" / > -< field -name = "state" > code < / field > -< field -name = "code" > - -# Aliases -self = record # res.partner.contract.annex - -seller = self.company_id -partner = self.partner_id - -# Functions -_ = self.contract_id._ -get_date = self.contract_id.get_date - -# Parse date -months = ["", - "января", "февраля", "марта", "апреля", - "мая", "июня", "июля", "августа", - "сентября", "октября", "ноября", "декабря", - ] -date = get_date() -dd = date.day -mm = date.month -yyyy = date.year -yy = yyyy % 100 -MM = months[mm] - -dd = dd if dd // 10 else '0{}'.format(dd) -mm = mm if mm // 10 else '0{}'.format(mm) - -order_date = self.order_id.date_order - -# ctx keys must be decalared in this xml with id equal to "contract_field_{technical_name}" -ctx = { - "contract_number": self.contract_id.name, - - "annex_name": self.name, - "annex_number": self.counter, - - "order_name": self.order_id.name, - "order_date": "{} {} {}".format(order_date.day, months[order_date.month], order_date.year), - - "design_cost": self.to_fixed(self.design_cost), - "design_period": self.design_period, - "design_doc_cost": self.to_fixed(self.design_doc_cost), - "design_doc_period": self.design_doc_period, - "delivery_address": self.delivery_address, - "delivery_period": self.delivery_period, - "installation_address": self.installation_address, - "installation_cost": self.to_fixed(self.installation_cost), - "installation_period": self.installation_period, - "total_cost": self.to_fixed(self.total_cost), - - "payment_part_one": self.payment_part_one, - "payment_part_two": self.payment_part_two, - "payment_part_three": self.payment_part_three, - "delivery_period": self.delivery_period, - - "dd": dd, - "mm": mm, - "MM": MM, - "yy": yy, - "yyyy": yyyy, - - "seller_name": seller.name_write, - "seller_company_form": _(dict(seller._fields['company_form'].selection).get(seller.company_form)), - "seller_representer_name": seller.representative_id.name, - "seller_representer_name_parent": seller.representative_id.name_genitive, - "seller_representer_name_initials": seller.representative_id.name_initials, - "seller_representer_function": seller.representative_id.function, - "seller_representer_function_parent": seller.representative_id.function_genitive, - - "seller_inn": seller.vat, - "seller_kpp": seller.iec, - "seller_ogrn": seller.psrn, - "seller_business_address": seller.full_address, - "seller_phone": seller.phone, - "seller_email": seller.email, - - "partner_name": partner.name_write, - "partner_representer_name": partner.representative_id.name, - "partner_representer_name_initials": partner.representative_id.name_initials, - "partner_inn": partner.vat, - "partner_business_address": partner.full_address, - "partner_phone": partner.phone, - "partner_email": partner.email, -} - -seller_bank = seller.bank_ids and seller.bank_ids[0] -if seller_bank: - bank = seller_bank.bank_id - bank_name = bank and bank.name or "" - bank_city = "г. {city}".format(city=bank.city) if bank and bank.city else "" - seller_bank_name = "{} {}".format(bank_name, bank_city).strip() - - ctx.update({ - "seller_bank": seller_bank_name, - "seller_rs": seller_bank.acc_number, - "seller_ks": bank.corr_account, - "seller_bic": bank.bic, - }) - -partner_bank = partner.bank_ids and partner.bank_ids[0] -if partner_bank: - bank = partner_bank.bank_id - bank_name = bank and bank.name or "" - bank_city = "г. {city}".format(city=bank.city) if bank and bank.city else "" - partner_bank_name = "{} {}".format(bank_name, bank_city).strip() - - ctx.update({ - "partner_bank": partner_bank_name, - "partner_rs": partner_bank.acc_number, - "partner_ks": bank.corr_account, - "partner_bic": bank.bic, - }) - -# Person -if not partner.is_company: - ctx.update({ - "partner_representer_name": partner.name_write, - "partner_representer_name_initials": partner.name_initials, - "partner_representer_passport_number": partner.passport_number, - "partner_representer_passport_date": partner.passport_date, - "partner_representer_passport_department": partner.passport_department, - }) - if not partner.name_write: - ctx.update({ - "partner_name": partner.name, - "partner_representer_name": partner.name, - }) -else: - # Company - ctx.update({ - "partner_company_form": _(dict(partner._fields['company_form'].selection).get(partner.company_form)), - "partner_representer_name_parent": partner.representative_id.name_genitive, - "partner_representer_document_parent": partner.representative_document, - "partner_representer_function": partner.representative_id.function, - "partner_representer_function_parent": partner.representative_id.function_genitive, - }) - - if partner.company_form == 'sp': - # Sole Proprietor - ctx.update({ - "partner_ip_number": partner.sp_register_number, - "partner_ip_date": partner.sp_register_date, - "partner_ogrnip": partner.psrn_sp, - "partner_representer_passport_number": partner.representative_id.passport_number, - "partner_representer_passport_date": partner.representative_id.passport_date, - "partner_representer_passport_department": partner.representative_id.passport_department, - }) - if partner.company_form == 'plc': - # Private Limited Company - ctx.update({ - "partner_kpp": partner.iec, - "partner_ogrn": partner.psrn, - }) - -action = ctx \ No newline at end of file diff --git a/utils/misc.py b/utils/misc.py index 65d4482..c2842e9 100755 --- a/utils/misc.py +++ b/utils/misc.py @@ -23,13 +23,13 @@ from odoo.tools.misc import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_ class Utils(models.AbstractModel): _name = "client_contracts.utils" - '''@staticmethod + """@staticmethod def parse_odoo_date(date: str): return dt.datetime.strptime(date, DEFAULT_SERVER_DATE_FORMAT) @staticmethod def parse_odoo_datetime(datetime: str): - return dt.datetime.strptime(datetime, DEFAULT_SERVER_DATETIME_FORMAT)''' + return dt.datetime.strptime(datetime, DEFAULT_SERVER_DATETIME_FORMAT)""" @staticmethod def to_fixed(number, digit=2): diff --git a/utils/num2words.py b/utils/num2words.py index bdafa58..54894a8 100755 --- a/utils/num2words.py +++ b/utils/num2words.py @@ -13,7 +13,7 @@ from num2words import CONVERTER_CLASSES, CONVERTES_TYPES # Jinja2 Global Method def num2words_(number, **kwargs): - if _performConvert(number): + if _perform_convert(number): if "lang" not in kwargs: kwargs["lang"] = "ru" if "to" not in kwargs or kwargs["to"] not in CONVERTES_TYPES: @@ -23,7 +23,7 @@ def num2words_(number, **kwargs): # Jinja2 Global Method def num2words_currency(number, **kwargs): - if _performConvert(number): + if _perform_convert(number): if "lang" not in kwargs: kwargs["lang"] = "ru" if "to" not in kwargs or kwargs["to"] not in CONVERTES_TYPES: @@ -34,7 +34,6 @@ def num2words_currency(number, **kwargs): total = result.split(",")[0] part_word = result.split()[-1] part_number = Decimal(str(number)) % 1 - return "{total}, {part_n} {part_w}".format( total=total.capitalize(), part_n="{:02d}".format(int(part_number * 100)), @@ -42,15 +41,13 @@ def num2words_currency(number, **kwargs): ) -def _performConvert(number): +def _perform_convert(number): if isinstance(number, int) or isinstance(number, float): return True - if isinstance(number, str): try: number = float(number) return True except ValueError: return False - return False diff --git a/views/res_partner_contract.xml b/views/res_partner_contract.xml index efaaac5..6e2c40d 100755 --- a/views/res_partner_contract.xml +++ b/views/res_partner_contract.xml @@ -41,8 +41,12 @@ - - + + diff --git a/views/sale_order.xml b/views/sale_order.xml index 628e31e..c6a8535 100755 --- a/views/sale_order.xml +++ b/views/sale_order.xml @@ -10,7 +10,7 @@ - + diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 14ed4e4..10cd356 100755 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -1,26 +1,23 @@ import base64 import logging -from odoo import api, fields, models -from odoo.exceptions import ValidationError +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError, UserError from ..utils import MODULE_NAME from ..utils.docxtpl import get_document_from_values_stream -# from ..utils.misc import Extension - _logger = logging.getLogger(__name__) -class ContractWizard(models.TransientModel): # , Extension): +class ContractWizard(models.TransientModel): _name = "res.partner.contract.wizard" _inherit = ["client_contracts.utils"] def _default_target(self): - _logger.debug("\n\n model: %s | id: %s \n\n", self.env.context.get("active_model"), self.env.context.get("self_id")) return "{model},{target_id}".format( - # model=self.active_model, target_id=int(self.env.context.get("self_id")) - model=self.env.context.get("active_model"), target_id=int(self.env.context.get("self_id")) + model=self.env.context.get("active_model"), + target_id=int(self.env.context.get("self_id")), ) def _default_document_template(self): @@ -34,7 +31,6 @@ class ContractWizard(models.TransientModel): # , Extension): "res.partner.contract.annex": "annex", }.get(self.active_model, False) company_type = self.env.context.get("company_form", False) - document_template_domain = [ ("template_type", "=", template_type), ("company_type", "=", company_type), @@ -48,14 +44,15 @@ class ContractWizard(models.TransientModel): # , Extension): ], string="Target", default=_default_target, + help="Record of contract or annex entity, from where wizard has been called", ) company_id = fields.Many2one( - "res.partner", + comodel_name="res.partner", string="Company", compute="_compute_company_id", ) partner_id = fields.Many2one( - "res.partner", + comodel_name="res.partner", string="Partner", compute="_compute_partner_id", ) @@ -63,7 +60,7 @@ class ContractWizard(models.TransientModel): # , Extension): string="Document Name", compute="_compute_document_name" ) document_template = fields.Many2one( - "res.partner.document.template", + comodel_name="res.partner.document.template", string="Document Template", default=_default_document_template, domain=lambda self: self._get_template_domain(), @@ -81,8 +78,10 @@ class ContractWizard(models.TransientModel): # , Extension): @api.depends("target") def _compute_company_id(self): - if self.target: - self.company_id = self.target.company_id + if self.target and self.target.company_id: + self.company_id = self.target.company_id.id + else: + self.company_id = self.env.company.id @api.depends("target") def _compute_partner_id(self): @@ -114,54 +113,72 @@ class ContractWizard(models.TransientModel): # , Extension): Looks as a tree view of *_contract_field_transient model in xml """ - def get_contract_field(technical_name): - return self.env["res.partner.contract.field"].search( - [ - ("technical_name", "=", technical_name), - ] + def get_contract_field_data(field_name, field_value): + rec = self.env["res.partner.contract.field"].search( + [("technical_name", "=", field_name)] ) + if not rec: + raise UserError( + _( + 'Field "%s" specified in template, not found in model "res.partner.contract.field"' + ) + % field_name + ) + return { + "contract_field_id": rec.id, + "visible": rec.visible, + "value": field_value, + } model_to_action = { "res.partner.contract": "action_get_contract_context", "res.partner.contract.annex": "action_get_annex_context", } - action = "{}.{}".format(MODULE_NAME, model_to_action[self.active_model]) + action_external_id = "{}.{}".format( + MODULE_NAME, model_to_action[self.active_model] + ) + action_rec = self.env.ref(action_external_id) + action_rec.model_id = ( + self.env["ir.model"].search([("model", "=", self.active_model)]).id + ) # Get dictionary for `transient_fields_ids` with editable fields # With data from Odoo database - contract_context_values = ( - self.env.ref(action).with_context({"onchange_self": self.target}).run() + contract_context_values = action_rec.with_context( + {"onchange_self": self.target} + ).run() + + transient_fields_data = [ + get_contract_field_data(field_name, field_value) + for field_name, field_value in contract_context_values.items() + ] + transient_fields_hidden_data = list( + filter(lambda item: not item["visible"], transient_fields_data) + ) + transient_fields_data = list( + filter(lambda item: item["visible"], transient_fields_data) ) - self.transient_field_ids = [ # one2many + self.transient_field_ids = [ ( - 4, + 6, + False, self.env["res.partner.contract.field.transient"] - .create( - { - "contract_field_id": get_contract_field(field).id, - "value": value, - } - ) - .id, - 0, - ) - for field, value in sorted( - contract_context_values.items(), - key=lambda tpl: self.env.ref( - "{}.contract_field_{}".format(MODULE_NAME, tpl[0]) - ).sequence, + .create(transient_fields_data) + .ids, + ) + ] + self.transient_field_ids_hidden = [ + ( + 6, + False, + self.env["res.partner.contract.field.transient"] + .create(transient_fields_hidden_data) + .ids, ) ] - self.transient_field_ids_hidden = ( - self.transient_field_ids - self.transient_field_ids.filtered("visible") - ) - self.transient_field_ids = ( - self.transient_field_ids - self.transient_field_ids_hidden - ) # Other - def get_docx_contract(self): template = self.document_template.attachment_id template_path = template._full_path(template.store_fname) @@ -252,11 +269,14 @@ class ContractWizard(models.TransientModel): # , Extension): "attachment_ids": [(4, result.id, False)], } ) - return result - def middleware_fields(self, kv): - + @staticmethod + def middleware_fields(kv): + """ + Removes items without values from dictionary. + :kv: dict. + """ # Debug False values empty = [] for k, v in list(kv.items()): @@ -264,7 +284,6 @@ class ContractWizard(models.TransientModel): # , Extension): empty.append(k) kv.pop(k) _logger.debug("Empty fields: {}".format(empty)) - return kv @property diff --git a/wizard/res_partner_contract_wizard.xml b/wizard/res_partner_contract_wizard.xml index febf2be..2890da8 100755 --- a/wizard/res_partner_contract_wizard.xml +++ b/wizard/res_partner_contract_wizard.xml @@ -10,12 +10,11 @@ - - +