diff --git a/stock_landed_costs_analytic/README.rst b/stock_landed_costs_analytic/README.rst new file mode 100644 index 0000000000..979d68ccbc --- /dev/null +++ b/stock_landed_costs_analytic/README.rst @@ -0,0 +1,64 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=========================== +Stock Landed Costs Analytic +=========================== + +This module adds an analytic account and analytic tags on landed costs lines +so that on landed costs validation account moves get analytic account and +analytic tags values from landed costs lines. + +Usage +===== + +To use this module, you need to: + +#. Create a Landed Cost +#. Set Analytic Account and Analytic Tags on your Additional Costs +#. Validate your Landed Cost +#. Each journal items created from your Landed Cost should have Analytic Account and Analytic Costs from Additional Cost if Account on journal item and on Additional Cost is the same. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/87/13.0 + +.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt +.. branch is "8.0" for example + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Benoit Aimont + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/stock_landed_costs_analytic/__init__.py b/stock_landed_costs_analytic/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/stock_landed_costs_analytic/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_landed_costs_analytic/__manifest__.py b/stock_landed_costs_analytic/__manifest__.py new file mode 100644 index 0000000000..ede0af054d --- /dev/null +++ b/stock_landed_costs_analytic/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Stock Landed Costs Analytic", + "summary": """ + This module adds an analytic account and analytic tags on landed costs + lines so that on landed costs validation account moves get analytic + account and analytic tags values from landed costs lines.""", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/account-analytic", + "depends": ["stock_landed_costs", "account_analytic_tag"], + "data": ["views/stock_landed_cost_lines.xml"], + "installable": True, + "demo": [], +} diff --git a/stock_landed_costs_analytic/i18n/es.po b/stock_landed_costs_analytic/i18n/es.po new file mode 100644 index 0000000000..017f16d8bb --- /dev/null +++ b/stock_landed_costs_analytic/i18n/es.po @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_landed_costs_analytic +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-03-26 18:46+0000\n" +"Last-Translator: eduardgm \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: stock_landed_costs_analytic +#: model:ir.model.fields,field_description:stock_landed_costs_analytic.field_stock_landed_cost_lines__analytic_distribution +msgid "Analytic" +msgstr "Analítico" + +#. module: stock_landed_costs_analytic +#: model:ir.model.fields,field_description:stock_landed_costs_analytic.field_stock_landed_cost_lines__analytic_tag_ids +msgid "Analytic Tags" +msgstr "Etiquetas analíticas" + +#. module: stock_landed_costs_analytic +#: model:ir.model,name:stock_landed_costs_analytic.model_stock_landed_cost_lines +msgid "Stock Landed Cost Line" +msgstr "Línea Existencias de Costes de destino" + +#. module: stock_landed_costs_analytic +#: model:ir.model,name:stock_landed_costs_analytic.model_stock_valuation_adjustment_lines +msgid "Valuation Adjustment Lines" +msgstr "Líneas de ajustes de valoración" diff --git a/stock_landed_costs_analytic/i18n/stock_landed_costs_analytic.pot b/stock_landed_costs_analytic/i18n/stock_landed_costs_analytic.pot new file mode 100644 index 0000000000..4558415c1f --- /dev/null +++ b/stock_landed_costs_analytic/i18n/stock_landed_costs_analytic.pot @@ -0,0 +1,34 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_landed_costs_analytic +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \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: stock_landed_costs_analytic +#: model:ir.model.fields,field_description:stock_landed_costs_analytic.field_stock_landed_cost_lines__analytic_distribution +msgid "Analytic" +msgstr "Analítico" + +#. module: stock_landed_costs_analytic +#: model:ir.model.fields,field_description:stock_landed_costs_analytic.field_stock_landed_cost_lines__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: stock_landed_costs_analytic +#: model:ir.model,name:stock_landed_costs_analytic.model_stock_landed_cost_lines +msgid "Stock Landed Cost Line" +msgstr "" + +#. module: stock_landed_costs_analytic +#: model:ir.model,name:stock_landed_costs_analytic.model_stock_valuation_adjustment_lines +msgid "Valuation Adjustment Lines" +msgstr "" diff --git a/stock_landed_costs_analytic/models/__init__.py b/stock_landed_costs_analytic/models/__init__.py new file mode 100644 index 0000000000..20f2100664 --- /dev/null +++ b/stock_landed_costs_analytic/models/__init__.py @@ -0,0 +1,3 @@ +from . import stock_landed_cost_lines +from . import stock_valuation_adjustment_lines +from . import stock_landed_cost diff --git a/stock_landed_costs_analytic/models/stock_landed_cost.py b/stock_landed_costs_analytic/models/stock_landed_cost.py new file mode 100644 index 0000000000..bd97044bcc --- /dev/null +++ b/stock_landed_costs_analytic/models/stock_landed_cost.py @@ -0,0 +1,10 @@ +from odoo import api, models + + +class StockLandedCost(models.Model): + _name = "stock.landed.cost" + _inherit = "stock.landed.cost" + + @api.model_create_multi + def create(self, vals_list): + return super().create(vals_list) diff --git a/stock_landed_costs_analytic/models/stock_landed_cost_lines.py b/stock_landed_costs_analytic/models/stock_landed_cost_lines.py new file mode 100644 index 0000000000..e19cd38d29 --- /dev/null +++ b/stock_landed_costs_analytic/models/stock_landed_cost_lines.py @@ -0,0 +1,11 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class StockLandedCostLines(models.Model): + _name = "stock.landed.cost.lines" + _inherit = ["stock.landed.cost.lines", "analytic.mixin"] + + analytic_tag_ids = fields.Many2many("account.analytic.tag", string="Analytic Tags") diff --git a/stock_landed_costs_analytic/models/stock_valuation_adjustment_lines.py b/stock_landed_costs_analytic/models/stock_valuation_adjustment_lines.py new file mode 100644 index 0000000000..94863edea4 --- /dev/null +++ b/stock_landed_costs_analytic/models/stock_valuation_adjustment_lines.py @@ -0,0 +1,28 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class StockValuationAdjustmentLines(models.Model): + _name = "stock.valuation.adjustment.lines" + _inherit = ["stock.valuation.adjustment.lines", "analytic.mixin"] + + def _create_account_move_line( + self, move, credit_account_id, debit_account_id, qty_out, already_out_account_id + ): + res = super()._create_account_move_line( + move, credit_account_id, debit_account_id, qty_out, already_out_account_id + ) + cost_line = self.cost_line_id + for line in res: + if line[2]["account_id"] == cost_line.account_id.id: + if cost_line.analytic_distribution: + line[2].update( + {"analytic_distribution": cost_line.analytic_distribution} + ) + if cost_line.analytic_tag_ids: + line[2].update( + {"analytic_tag_ids": [(6, 0, cost_line.analytic_tag_ids.ids)]} + ) + return res diff --git a/stock_landed_costs_analytic/pyproject.toml b/stock_landed_costs_analytic/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/stock_landed_costs_analytic/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/stock_landed_costs_analytic/static/description/icon.png b/stock_landed_costs_analytic/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/stock_landed_costs_analytic/static/description/icon.png differ diff --git a/stock_landed_costs_analytic/tests/__init__.py b/stock_landed_costs_analytic/tests/__init__.py new file mode 100644 index 0000000000..a8e9090117 --- /dev/null +++ b/stock_landed_costs_analytic/tests/__init__.py @@ -0,0 +1 @@ +from . import test_stock_landed_costs_analytic diff --git a/stock_landed_costs_analytic/tests/test_stock_landed_costs_analytic.py b/stock_landed_costs_analytic/tests/test_stock_landed_costs_analytic.py new file mode 100644 index 0000000000..918c3d0c92 --- /dev/null +++ b/stock_landed_costs_analytic/tests/test_stock_landed_costs_analytic.py @@ -0,0 +1,134 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestStockLandedCostsAnalytic(TransactionCase): + def setUp(self): + super().setUp() + self.Product = self.env["product.product"] + self.Picking = self.env["stock.picking"] + self.LandedCost = self.env["stock.landed.cost"] + self.ProductCategory = self.env["product.category"] + self.AnalyticTag = self.env["account.analytic.tag"] + self.Account = self.env["account.account"] + + self.analytic_tag_1 = self.AnalyticTag.create({"name": "analytic tag test 1"}) + self.analytic_tag_2 = self.AnalyticTag.create({"name": "analytic tag test 2"}) + self.analytic_distribution_1 = dict( + {str(self.env.ref("analytic.analytic_agrolait").id): 100.0} + ) + self.analytic_distribution_2 = dict( + {str(self.env.ref("analytic.analytic_asustek").id): 100.0} + ) + self.picking_type_in = self.env.ref("stock.picking_type_out") + self.supplier_location = self.env.ref("stock.stock_location_suppliers") + self.customer_location = self.env.ref("stock.stock_location_customers") + + self.account_1 = self.Account.create( + { + "name": "Account 1 test", + "code": "Account1", + "account_type": self.env["account.account"] + .search([], limit=1) + .account_type, + "reconcile": True, + } + ) + self.account_2 = self.Account.create( + { + "name": "Account 2 test", + "code": "Account2", + "account_type": self.env["account.account"] + .search([], limit=1) + .account_type, + "reconcile": True, + } + ) + self.category = self.ProductCategory.create( + { + "name": "Product Category Test", + "property_cost_method": "fifo", + "property_valuation": "real_time", + } + ) + self.product = self.Product.create( + { + "name": "Product Test", + "type": "product", + "standard_price": 1.0, + "categ_id": self.category.id, + } + ) + self.landed_cost_product = self.Product.create( + {"name": "Landed Cost Product Test", "type": "service"} + ) + + picking_vals = { + "name": "Landed Cost Picking Test", + "picking_type_id": self.picking_type_in.id, + "location_id": self.supplier_location.id, + "location_dest_id": self.customer_location.id, + "move_ids": [ + ( + 0, + 0, + { + "name": "Move Test", + "product_id": self.product.id, + "product_uom_qty": 5, + "quantity": 5, + "product_uom": self.ref("uom.product_uom_unit"), + "location_id": self.supplier_location.id, + "location_dest_id": self.customer_location.id, + }, + ) + ], + } + picking_landed_cost = self.Picking.create(picking_vals) + landed_cost_vals = { + "picking_ids": [picking_landed_cost.id], + "cost_lines": [ + ( + 0, + 0, + { + "product_id": self.landed_cost_product.id, + "price_unit": 2.0, + "split_method": "equal", + "account_id": self.account_1.id, + "analytic_distribution": self.analytic_distribution_1, + "analytic_tag_ids": [(6, 0, self.analytic_tag_1.ids)], + }, + ), + ( + 0, + 0, + { + "product_id": self.landed_cost_product.id, + "price_unit": 4.0, + "split_method": "equal", + "account_id": self.account_2.id, + "analytic_distribution": self.analytic_distribution_2, + "analytic_tag_ids": [(6, 0, self.analytic_tag_2.ids)], + }, + ), + ], + } + self.landed_cost = self.LandedCost.create(landed_cost_vals) + + def test_stock_landed_costs_analytic(self): + self.landed_cost.button_validate() + self.assertTrue(self.landed_cost.account_move_id) + for line in self.landed_cost.account_move_id.line_ids: + if line.account_id == self.account_1: + self.assertEqual(line.analytic_tag_ids.ids, self.analytic_tag_1.ids) + self.assertEqual( + line.analytic_distribution, self.analytic_distribution_1 + ) + if line.account_id == self.account_2: + self.assertEqual(line.analytic_tag_ids.ids, self.analytic_tag_2.ids) + self.assertEqual( + line.analytic_distribution, self.analytic_distribution_2 + ) diff --git a/stock_landed_costs_analytic/views/stock_landed_cost_lines.xml b/stock_landed_costs_analytic/views/stock_landed_cost_lines.xml new file mode 100644 index 0000000000..6c78f3f282 --- /dev/null +++ b/stock_landed_costs_analytic/views/stock_landed_cost_lines.xml @@ -0,0 +1,26 @@ + + + + + stock.landed.cost.form (in stock_landed_costs_analytic) + stock.landed.cost + + + + + + + + +