Merge branch 'staging' into 'development'

Staging

See merge request tabulasense/client_contracts!9
This commit is contained in:
Иван Широких 2020-01-28 12:37:37 +05:00
commit deade69594
12 changed files with 261 additions and 165 deletions

11
TODOLIST.md Normal file
View File

@ -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

View File

@ -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",

View File

@ -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),

View File

@ -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}"

View File

@ -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):

View File

@ -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):

View File

@ -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=[

View File

@ -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)

View File

@ -3,7 +3,7 @@
<!-- res.partner.contract.field action window -->
<record id="res_partner_contract_field_action" model="ir.actions.act_window">
<field name="name">res.partner.contract.field.action</field>
<field name="name">Contract Fields</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner.contract.field</field>
<field name="view_mode">tree,form</field>
@ -12,7 +12,7 @@
<!-- res.partner.document.template action window -->
<record id="res_partner_document_template_action" model="ir.actions.act_window">
<field name="name">res.partner.document.template.action</field>
<field name="name">Document Templates</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner.document.template</field>
<field name="view_mode">tree,form</field>
@ -87,7 +87,7 @@
parent="res_partner_menu_contracts"
sequence="1"/>
<menuitem id="res_partner_menu_contracts_templates_"
<menuitem id="res_partner_menu_contracts_templates"
name="Templates"
parent="res_partner_menu_contracts"
action="res_partner_document_template_action"

View File

@ -12,6 +12,7 @@
<sheet>
<group name="options" invisible="1">
<field name="display_name" invisible="1"/>
<field name="currency_id" invisible="1"/>
</group>
<group name="info" string="Info">
<field name="name" placeholder="Leave empty for compute"/>

View File

@ -0,0 +1,20 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<data>
<!-- res.partner.contract.field tree view -->
<record id="res_partner_contract_field_view_tree" model="ir.ui.view">
<field name="name">res.partner.contract.field.view.tree</field>
<field name="model">res.partner.contract.field</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="description"/>
<field name="technical_name"/>
<field name="visible"/>
</tree>
</field>
</record>
</data>
</odoo>

View File

@ -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):