diff --git a/sale_contract_by_template/__init__.py b/sale_contract_by_template/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/sale_contract_by_template/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_contract_by_template/__manifest__.py b/sale_contract_by_template/__manifest__.py new file mode 100644 index 000000000..19d8c8d71 --- /dev/null +++ b/sale_contract_by_template/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2022 Oihane Crucelaegui - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "Sale Contract", + "version": "14.0.1.0.0", + "category": "Sales", + "license": "AGPL-3", + "author": "AvanzOSC", + "website": "https://github.com/avanzosc/sale-addons", + "depends": [ + "contract", + "contract_sale", + "sale", + ], + "excludes": [], + "data": [ + "views/contract_contract_views.xml", + "views/product_views.xml", + "views/sale_order_views.xml", + ], + "installable": True, +} diff --git a/sale_contract_by_template/i18n/es.po b/sale_contract_by_template/i18n/es.po new file mode 100644 index 000000000..6edfdd260 --- /dev/null +++ b/sale_contract_by_template/i18n/es.po @@ -0,0 +1,91 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_contract_by_template +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-11-23 14:07+0000\n" +"PO-Revision-Date: 2022-11-23 14:07+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_contract_contract +msgid "Contract" +msgstr "Contrato" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_count +msgid "Contract Count" +msgstr "Nº de contratos" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__contract_tmpl_id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__contract_tmpl_id +msgid "Contract Template" +msgstr "Plantilla de contrato" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_ids +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__contract_ids +#: model_terms:ir.ui.view,arch_db:sale_contract_by_template.sale_order_view_form +msgid "Contracts" +msgstr "Contratos" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__id +msgid "ID" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line____last_update +msgid "Last Modified on" +msgstr "Última Modificación en" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_product +msgid "Product" +msgstr "Producto" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_template +msgid "Product Template" +msgstr "Plantilla de producto" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__sale_line_id +msgid "Sale Order Line" +msgstr "Línea de pedido de venta" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order +msgid "Sales Order" +msgstr "Pedido de venta" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línea de pedido de venta" diff --git a/sale_contract_by_template/i18n/fr.po b/sale_contract_by_template/i18n/fr.po new file mode 100644 index 000000000..ad087c267 --- /dev/null +++ b/sale_contract_by_template/i18n/fr.po @@ -0,0 +1,91 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_contract_by_template +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-11-23 14:06+0000\n" +"PO-Revision-Date: 2022-11-23 14:06+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_contract_contract +msgid "Contract" +msgstr "Contrat" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_count +msgid "Contract Count" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__contract_tmpl_id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__contract_tmpl_id +msgid "Contract Template" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_ids +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__contract_ids +#: model_terms:ir.ui.view,arch_db:sale_contract_by_template.sale_order_view_form +msgid "Contracts" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__display_name +msgid "Display Name" +msgstr "Nom à afficher" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__id +msgid "ID" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_product +msgid "Product" +msgstr "Article" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_template +msgid "Product Template" +msgstr "Modèle d'article" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__sale_line_id +msgid "Sale Order Line" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order +msgid "Sales Order" +msgstr "Bon de commande" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order_line +msgid "Sales Order Line" +msgstr "Ligne de bons de commande" diff --git a/sale_contract_by_template/i18n/pt.po b/sale_contract_by_template/i18n/pt.po new file mode 100644 index 000000000..a4116caff --- /dev/null +++ b/sale_contract_by_template/i18n/pt.po @@ -0,0 +1,91 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_contract_by_template +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-11-23 14:06+0000\n" +"PO-Revision-Date: 2022-11-23 14:06+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_contract_contract +msgid "Contract" +msgstr "Contrato" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_count +msgid "Contract Count" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__contract_tmpl_id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__contract_tmpl_id +msgid "Contract Template" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_ids +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__contract_ids +#: model_terms:ir.ui.view,arch_db:sale_contract_by_template.sale_order_view_form +msgid "Contracts" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__display_name +msgid "Display Name" +msgstr "Nome a Apresentar" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__id +msgid "ID" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line____last_update +msgid "Last Modified on" +msgstr "Última Modificação Em" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_product +msgid "Product" +msgstr "Artigo" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_template +msgid "Product Template" +msgstr "Modelo de Artigo" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__sale_line_id +msgid "Sale Order Line" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order +msgid "Sales Order" +msgstr "Ordem de Vendas" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order_line +msgid "Sales Order Line" +msgstr "Linhas da Ordem de Vendas" diff --git a/sale_contract_by_template/i18n/sale_contract_by_template.pot b/sale_contract_by_template/i18n/sale_contract_by_template.pot new file mode 100644 index 000000000..9cd0a629a --- /dev/null +++ b/sale_contract_by_template/i18n/sale_contract_by_template.pot @@ -0,0 +1,91 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_contract_by_template +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-11-23 14:06+0000\n" +"PO-Revision-Date: 2022-11-23 14:06+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_contract_contract +msgid "Contract" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_count +msgid "Contract Count" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__contract_tmpl_id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__contract_tmpl_id +msgid "Contract Template" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__contract_ids +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__contract_ids +#: model_terms:ir.ui.view,arch_db:sale_contract_by_template.sale_order_view_form +msgid "Contracts" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__display_name +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__display_name +msgid "Display Name" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order__id +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line__id +msgid "ID" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_product____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_product_template____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order____last_update +#: model:ir.model.fields,field_description:sale_contract_by_template.field_sale_order_line____last_update +msgid "Last Modified on" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_product +msgid "Product" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_product_template +msgid "Product Template" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model.fields,field_description:sale_contract_by_template.field_contract_contract__sale_line_id +msgid "Sale Order Line" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_contract_by_template +#: model:ir.model,name:sale_contract_by_template.model_sale_order_line +msgid "Sales Order Line" +msgstr "" diff --git a/sale_contract_by_template/models/__init__.py b/sale_contract_by_template/models/__init__.py new file mode 100644 index 000000000..38dcbd5d4 --- /dev/null +++ b/sale_contract_by_template/models/__init__.py @@ -0,0 +1,4 @@ +from . import contract_contract +from . import product +from . import sale_order +from . import sale_order_line diff --git a/sale_contract_by_template/models/contract_contract.py b/sale_contract_by_template/models/contract_contract.py new file mode 100644 index 000000000..f3585c209 --- /dev/null +++ b/sale_contract_by_template/models/contract_contract.py @@ -0,0 +1,13 @@ +# Copyright 2022 Oihane Crucelaegui - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ContractContract(models.Model): + _inherit = "contract.contract" + + sale_line_id = fields.Many2one( + comodel_name="sale.order.line", + string="Sale Order Line", + ) diff --git a/sale_contract_by_template/models/product.py b/sale_contract_by_template/models/product.py new file mode 100644 index 000000000..646dd8235 --- /dev/null +++ b/sale_contract_by_template/models/product.py @@ -0,0 +1,53 @@ +# Copyright 2022 Oihane Crucelaegui - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + contract_tmpl_id = fields.Many2one( + comodel_name="contract.template", + string="Contract Template", + compute="_compute_contract_template", + inverse="_inverse_contract_template", + search="_search_contract_template", + ) + + @api.depends_context("company") + @api.depends("product_variant_ids", "product_variant_ids.contract_tmpl_id") + def _compute_contract_template(self): + # Depends on force_company context because contract_tmpl_id is company_dependent + # on the product_product + unique_variants = self.filtered( + lambda template: len(template.product_variant_ids) == 1 + ) + for template in unique_variants: + template.contract_tmpl_id = template.product_variant_ids.contract_tmpl_id + for template in self - unique_variants: + template.contract_tmpl_id = False + + def _inverse_contract_template(self): + for template in self: + if len(template.product_variant_ids) == 1: + template.product_variant_ids.contract_tmpl_id = ( + template.contract_tmpl_id + ) + + def _search_contract_template(self, operator, value): + products = self.env["product.product"].search( + [("contract_tmpl_id", operator, value)], limit=None + ) + return [("id", "in", products.mapped("product_tmpl_id").ids)] + + +class ProductProduct(models.Model): + _inherit = "product.product" + + contract_tmpl_id = fields.Many2one( + comodel_name="contract.template", + string="Contract Template", + domain="[('contract_type', '=', 'sale')]", + company_dependent=True, + ) diff --git a/sale_contract_by_template/models/sale_order.py b/sale_contract_by_template/models/sale_order.py new file mode 100644 index 000000000..7edaf38f6 --- /dev/null +++ b/sale_contract_by_template/models/sale_order.py @@ -0,0 +1,71 @@ +# Copyright 2022 Oihane Crucelaegui - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + contract_count = fields.Integer( + string="Contract Count", + compute="_compute_contract_id", + readonly=True, + ) + contract_ids = fields.Many2many( + comodel_name="contract.contract", + string="Contracts", + compute="_compute_contract_id", + readonly=True, + copy=False, + ) + + @api.depends("order_line.contract_ids") + def _compute_contract_id(self): + for order in self: + contracts = order.mapped("order_line.contract_ids") + order.contract_ids = contracts + order.contract_count = len(contracts) + + def action_view_contract(self): + contracts = self.mapped("contract_ids") + action = self.env["ir.actions.actions"]._for_xml_id( + "contract.action_customer_contract" + ) + if len(contracts) > 1: + action["domain"] = [("id", "in", contracts.ids)] + elif len(contracts) == 1: + form_view = [ + ( + self.env.ref("contract.contract_contract_customer_form_view").id, + "form", + ) + ] + if "views" in action: + action["views"] = form_view + [ + (state, view) for state, view in action["views"] if view != "form" + ] + else: + action["views"] = form_view + action["res_id"] = contracts.id + else: + action = {"type": "ir.actions.act_window_close"} + + context = {} + if len(self) == 1: + context.update( + { + "default_partner_id": self.partner_id.id, + "default_user_id": self.user_id.id, + } + ) + action["context"] = context + return action + + def _action_confirm(self): + """On SO confirmation, some lines should generate a contract.""" + result = super()._action_confirm() + if len(self.company_id) == 1: + # All orders are in the same company + self.order_line.sudo()._contract_generation() + return result diff --git a/sale_contract_by_template/models/sale_order_line.py b/sale_contract_by_template/models/sale_order_line.py new file mode 100644 index 000000000..30cada2bf --- /dev/null +++ b/sale_contract_by_template/models/sale_order_line.py @@ -0,0 +1,74 @@ +# Copyright 2022 Oihane Crucelaegui - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +# EL MODULO contract_sale_generation crea un campo llamado contract_line_id en las +# líneas de pedido, pero el funcionamiento es a la inversa de lo que queremos. +# Así que hay que recordar no llamarlo igual, por si acaso. + +from odoo import api, fields, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + contract_ids = fields.One2many( + comodel_name="contract.contract", + inverse_name="sale_line_id", + string="Contracts", + ) + + # no trigger product_id.invoice_policy to avoid retroactively changing SO + @api.depends("qty_invoiced", "qty_delivered", "product_uom_qty", "order_id.state") + def _get_to_invoice_qty(self): + super()._get_to_invoice_qty() + for line in self: + if line.product_id.contract_tmpl_id: + line.qty_to_invoice = 0 + + def _prepare_contract(self): + self.ensure_one() + contract = self.env["contract.contract"].new( + { + "contract_type": "sale", + "name": self.display_name, + "partner_id": self.order_partner_id.id, + "invoice_partner_id": self.order_id.partner_invoice_id.id, + "company_id": self.company_id.id, + "user_id": self.salesman_id.id, + "contract_template_id": self.product_id.contract_tmpl_id.id, + "sale_line_id": self.id, + "line_recurrence": True, + } + ) + contract._onchange_partner_id() + if self.order_id.partner_invoice_id: + contract.invoice_partner_id = self.order_id.partner_invoice_id.id + if self.order_id.pricelist_id: + contract.pricelist_id = (self.order_id.pricelist_id.id,) + if self.order_id.payment_term_id: + contract.payment_term_id = self.order_id.payment_term_id.id + if self.order_id.fiscal_position_id: + contract.fiscal_position_id = self.order_id.fiscal_position_id.id + # Get other contract values from template onchange + contract._onchange_contract_template_id() + return contract._convert_to_write(contract._cache) + + def _prepare_contract_values(self): + contracts_values = [] + for sale_line in self: + for _cnt in range(int(sale_line.product_uom_qty)): + contracts_values.append(sale_line._prepare_contract()) + return contracts_values + + @api.model_create_multi + def create(self, vals_list): + lines = super().create(vals_list) + for line in lines: + if line.state == "sale" and line.product_id.contract_tmpl_id: + line.sudo()._contract_generation() + return lines + + def _contract_generation(self): + contract_values = self._prepare_contract_values() + contracts = self.env["contract.contract"].create(contract_values) + return contracts diff --git a/sale_contract_by_template/views/contract_contract_views.xml b/sale_contract_by_template/views/contract_contract_views.xml new file mode 100644 index 000000000..3465f19f3 --- /dev/null +++ b/sale_contract_by_template/views/contract_contract_views.xml @@ -0,0 +1,12 @@ + + + + contract.contract + + + + + + + + diff --git a/sale_contract_by_template/views/product_views.xml b/sale_contract_by_template/views/product_views.xml new file mode 100644 index 000000000..1d2d31ac6 --- /dev/null +++ b/sale_contract_by_template/views/product_views.xml @@ -0,0 +1,15 @@ + + + + product.template + + + + + + + + diff --git a/sale_contract_by_template/views/sale_order_views.xml b/sale_contract_by_template/views/sale_order_views.xml new file mode 100644 index 000000000..23ef0856f --- /dev/null +++ b/sale_contract_by_template/views/sale_order_views.xml @@ -0,0 +1,33 @@ + + + + sale.order + + +
+ +
+ +
+
+
+
+
+
diff --git a/setup/sale_contract_by_template/odoo/addons/sale_contract_by_template b/setup/sale_contract_by_template/odoo/addons/sale_contract_by_template new file mode 120000 index 000000000..233dcd1ee --- /dev/null +++ b/setup/sale_contract_by_template/odoo/addons/sale_contract_by_template @@ -0,0 +1 @@ +../../../../sale_contract_by_template \ No newline at end of file diff --git a/setup/sale_contract_by_template/setup.py b/setup/sale_contract_by_template/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/sale_contract_by_template/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)