mirror of
https://github.com/OCA/account-financial-tools.git
synced 2025-02-02 12:47:26 +02:00
[IMP] stock_account_anglo_saxon_cogs_kit: correct account in vendor bills for purchase of consumable kit
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
"name": "Stock Account Anglo Saxon COGS Kit",
|
||||
"category": "Accounting",
|
||||
"version": "16.0.1.0.0",
|
||||
"depends": ["sale_mrp"],
|
||||
"depends": ["sale_mrp", "purchase_mrp"],
|
||||
"data": [],
|
||||
"author": "ForgeFlow, Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/account-financial-tools",
|
||||
|
||||
@@ -12,3 +12,9 @@ class AccountMoveLine(models.Model):
|
||||
p.type == "product" and p.valuation == "real_time"
|
||||
for p in self.sale_line_ids.mapped("move_ids.product_id")
|
||||
)
|
||||
|
||||
def _can_use_stock_accounts(self):
|
||||
return super()._can_use_stock_accounts() or any(
|
||||
p.type == "product" and p.valuation == "real_time"
|
||||
for p in self.purchase_line_id.mapped("move_ids.product_id")
|
||||
)
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
|
||||
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
||||
<title>Stock Account Anglo Saxon COGS Kit</title>
|
||||
<style type="text/css">
|
||||
|
||||
/*
|
||||
:Author: David Goodger (goodger@python.org)
|
||||
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
|
||||
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the HTML output of Docutils.
|
||||
|
||||
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
|
||||
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
||||
customize this style sheet.
|
||||
*/
|
||||
|
||||
@@ -369,7 +368,7 @@ ul.auto-toc {
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:95246b5c8140145c330025892f1165ea1839841376ce1796732d29fb5b4c1962
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/16.0/stock_account_anglo_saxon_cogs_kit"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/account-financial-tools-16-0/account-financial-tools-16-0-stock_account_anglo_saxon_cogs_kit"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-financial-tools/tree/16.0/stock_account_anglo_saxon_cogs_kit"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-financial-tools-16-0/account-financial-tools-16-0-stock_account_anglo_saxon_cogs_kit"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
||||
<p>The Odoo Official documentation recommends to use consumable for kit products and only to be
|
||||
storable in case Anglosaxon accounting:</p>
|
||||
<p><a class="reference external" href="https://www.odoo.com/documentation/16.0/applications/inventory_and_mrp/manufacturing/management/kit_shipping.html">https://www.odoo.com/documentation/16.0/applications/inventory_and_mrp/manufacturing/management/kit_shipping.html</a></p>
|
||||
@@ -382,17 +381,17 @@ storable if they don’t want to track quantities for the kit.</p>
|
||||
<p><strong>Table of contents</strong></p>
|
||||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#bug-tracker" id="id1">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="id2">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="id3">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="id4">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="id5">Maintainers</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="bug-tracker">
|
||||
<h1><a class="toc-backref" href="#id1">Bug Tracker</a></h1>
|
||||
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||
@@ -400,15 +399,15 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
<h1><a class="toc-backref" href="#id2">Credits</a></h1>
|
||||
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
|
||||
<div class="section" id="authors">
|
||||
<h2><a class="toc-backref" href="#id3">Authors</a></h2>
|
||||
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>ForgeFlow</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributors">
|
||||
<h2><a class="toc-backref" href="#id4">Contributors</a></h2>
|
||||
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>ForgeFlow, S.L. (<a class="reference external" href="https://www.forgeflow.com">https://www.forgeflow.com</a>)
|
||||
* Marina Alapont <<a class="reference external" href="mailto:marina.alapont@forgeflow.com">marina.alapont@forgeflow.com</a>>
|
||||
@@ -416,14 +415,14 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="maintainers">
|
||||
<h2><a class="toc-backref" href="#id5">Maintainers</a></h2>
|
||||
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
|
||||
<p>This module is maintained by the OCA.</p>
|
||||
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
|
||||
<p>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.</p>
|
||||
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainers</a>:</p>
|
||||
<p><a class="reference external" href="https://github.com/MarinaAForgeFlow"><img alt="MarinaAForgeFlow" src="https://github.com/MarinaAForgeFlow.png?size=40px" /></a> <a class="reference external" href="https://github.com/AaronHForgeFlow"><img alt="AaronHForgeFlow" src="https://github.com/AaronHForgeFlow.png?size=40px" /></a></p>
|
||||
<p><a class="reference external image-reference" href="https://github.com/MarinaAForgeFlow"><img alt="MarinaAForgeFlow" src="https://github.com/MarinaAForgeFlow.png?size=40px" /></a> <a class="reference external image-reference" href="https://github.com/AaronHForgeFlow"><img alt="AaronHForgeFlow" src="https://github.com/AaronHForgeFlow.png?size=40px" /></a></p>
|
||||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/16.0/stock_account_anglo_saxon_cogs_kit">OCA/account-financial-tools</a> project on GitHub.</p>
|
||||
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
||||
</div>
|
||||
|
||||
@@ -17,31 +17,21 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
cls.ProductCategory = cls.env["product.category"]
|
||||
cls.categ_unit = cls.env.ref("uom.product_uom_categ_unit")
|
||||
|
||||
def test_01_sale_mrp_anglo_saxon(self):
|
||||
"""Test sale order for kit, deliver and invoice and ensure
|
||||
COGS is hit
|
||||
"""
|
||||
self.env.company.currency_id = self.env.ref("base.USD")
|
||||
self.uom_unit = self.UoM.create(
|
||||
cls.env.company.currency_id = cls.env.ref("base.USD")
|
||||
cls.uom_unit = cls.UoM.create(
|
||||
{
|
||||
"name": "Test-Unit",
|
||||
"category_id": self.categ_unit.id,
|
||||
"category_id": cls.categ_unit.id,
|
||||
"factor": 1,
|
||||
"uom_type": "bigger",
|
||||
"rounding": 1.0,
|
||||
}
|
||||
)
|
||||
self.company = self.env.ref("base.main_company")
|
||||
self.company.anglo_saxon_accounting = True
|
||||
self.partner = self.env.ref("base.res_partner_1")
|
||||
self.category = self.env.ref("product.product_category_1").copy(
|
||||
{
|
||||
"name": "Test category",
|
||||
"property_valuation": "real_time",
|
||||
"property_cost_method": "fifo",
|
||||
}
|
||||
)
|
||||
account_receiv = self.env["account.account"].create(
|
||||
# Configure company
|
||||
cls.company = cls.env.ref("base.main_company")
|
||||
cls.company.anglo_saxon_accounting = True
|
||||
# Create accounts
|
||||
cls.account_receiv = cls.env["account.account"].create(
|
||||
{
|
||||
"name": "Receivable",
|
||||
"code": "RCV00",
|
||||
@@ -49,7 +39,7 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
account_expense = self.env["account.account"].create(
|
||||
cls.account_expense = cls.env["account.account"].create(
|
||||
{
|
||||
"name": "Expense",
|
||||
"code": "EXP00",
|
||||
@@ -57,7 +47,7 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
account_input = self.env["account.account"].create(
|
||||
cls.account_input = cls.env["account.account"].create(
|
||||
{
|
||||
"name": "Input",
|
||||
"code": "IN00",
|
||||
@@ -65,7 +55,7 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
account_output = self.env["account.account"].create(
|
||||
cls.account_output = cls.env["account.account"].create(
|
||||
{
|
||||
"name": "Output",
|
||||
"code": "OUT00",
|
||||
@@ -73,7 +63,7 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
account_valuation = self.env["account.account"].create(
|
||||
cls.account_valuation = cls.env["account.account"].create(
|
||||
{
|
||||
"name": "Valuation",
|
||||
"code": "STV00",
|
||||
@@ -81,43 +71,78 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
self.partner.property_account_receivable_id = account_receiv
|
||||
self.category.property_stock_account_input_categ_id = account_input
|
||||
self.category.property_stock_account_output_categ_id = account_output
|
||||
self.category.property_stock_valuation_account_id = account_valuation
|
||||
self.category.property_account_expense_categ_id = account_expense
|
||||
self.category.property_stock_journal = self.env["account.journal"].create(
|
||||
# Configure partner and products
|
||||
cls.partner = cls.env.ref("base.res_partner_1")
|
||||
cls.category = cls.env.ref("product.product_category_1").copy(
|
||||
{
|
||||
"name": "Test category",
|
||||
"property_valuation": "real_time",
|
||||
"property_cost_method": "fifo",
|
||||
}
|
||||
)
|
||||
cls.partner.property_account_receivable_id = cls.account_receiv
|
||||
cls.category.property_stock_account_input_categ_id = cls.account_input
|
||||
cls.category.property_stock_account_output_categ_id = cls.account_output
|
||||
cls.category.property_stock_valuation_account_id = cls.account_valuation
|
||||
cls.category.property_account_expense_categ_id = cls.account_expense
|
||||
cls.category.property_stock_journal = cls.env["account.journal"].create(
|
||||
{"name": "Stock journal", "type": "sale", "code": "STK00"}
|
||||
)
|
||||
|
||||
Product = self.env["product.product"]
|
||||
self.finished_product = Product.create(
|
||||
Product = cls.env["product.product"]
|
||||
cls.finished_product = Product.create(
|
||||
{
|
||||
"name": "KIT product",
|
||||
"type": "consu",
|
||||
"uom_id": self.uom_unit.id,
|
||||
"uom_id": cls.uom_unit.id,
|
||||
"invoice_policy": "delivery",
|
||||
"categ_id": self.category.id,
|
||||
"categ_id": cls.category.id,
|
||||
}
|
||||
)
|
||||
self.component1 = Product.create(
|
||||
cls.component1 = Product.create(
|
||||
{
|
||||
"name": "Component 1",
|
||||
"type": "product",
|
||||
"uom_id": self.uom_unit.id,
|
||||
"categ_id": self.category.id,
|
||||
"uom_id": cls.uom_unit.id,
|
||||
"categ_id": cls.category.id,
|
||||
"standard_price": 20,
|
||||
}
|
||||
)
|
||||
self.component2 = Product.create(
|
||||
cls.component2 = Product.create(
|
||||
{
|
||||
"name": "Component 2",
|
||||
"type": "product",
|
||||
"uom_id": self.uom_unit.id,
|
||||
"categ_id": self.category.id,
|
||||
"uom_id": cls.uom_unit.id,
|
||||
"categ_id": cls.category.id,
|
||||
"standard_price": 10,
|
||||
}
|
||||
)
|
||||
kit = cls.env["mrp.bom"].create(
|
||||
{
|
||||
"product_tmpl_id": cls.finished_product.product_tmpl_id.id,
|
||||
"product_qty": 1.0,
|
||||
"type": "phantom",
|
||||
}
|
||||
)
|
||||
BomLine = cls.env["mrp.bom.line"]
|
||||
BomLine.create(
|
||||
{
|
||||
"product_id": cls.component1.id,
|
||||
"product_qty": 2.0,
|
||||
"bom_id": kit.id,
|
||||
}
|
||||
)
|
||||
BomLine.create(
|
||||
{
|
||||
"product_id": cls.component2.id,
|
||||
"product_qty": 1.0,
|
||||
"bom_id": kit.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_01_sale_mrp_anglo_saxon(self):
|
||||
"""Test sale order for kit, deliver and invoice and ensure
|
||||
COGS is hit
|
||||
"""
|
||||
self.env["stock.quant"].create(
|
||||
{
|
||||
"product_id": self.component1.id,
|
||||
@@ -132,28 +157,6 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
"quantity": 3.0,
|
||||
}
|
||||
)
|
||||
kit = self.env["mrp.bom"].create(
|
||||
{
|
||||
"product_tmpl_id": self.finished_product.product_tmpl_id.id,
|
||||
"product_qty": 1.0,
|
||||
"type": "phantom",
|
||||
}
|
||||
)
|
||||
BomLine = self.env["mrp.bom.line"]
|
||||
BomLine.create(
|
||||
{
|
||||
"product_id": self.component1.id,
|
||||
"product_qty": 2.0,
|
||||
"bom_id": kit.id,
|
||||
}
|
||||
)
|
||||
BomLine.create(
|
||||
{
|
||||
"product_id": self.component2.id,
|
||||
"product_qty": 1.0,
|
||||
"bom_id": kit.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create a SO for a specific partner for three units of the
|
||||
# finished product
|
||||
@@ -200,8 +203,8 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
self.invoice = move_form.save()
|
||||
self.invoice.action_post()
|
||||
aml = self.invoice.line_ids
|
||||
aml_expense = aml.filtered(lambda l: l.account_id == account_expense)
|
||||
aml_output = aml.filtered(lambda l: l.account_id == account_output)
|
||||
aml_expense = aml.filtered(lambda l: l.account_id == self.account_expense)
|
||||
aml_output = aml.filtered(lambda l: l.account_id == self.account_output)
|
||||
# Check that the cost of Good Sold entries are equal to:
|
||||
# 2* (2 * 20 + 1 * 10) = 100
|
||||
self.assertEqual(
|
||||
@@ -217,14 +220,65 @@ class TestStockAccountAngloSaxonCogsKit(common.TransactionCase):
|
||||
self.assertNotEqual(
|
||||
aml.filtered(
|
||||
lambda ml: ml.product_id == self.finished_product
|
||||
and ml.account_id == account_expense
|
||||
and ml.account_id == self.account_expense
|
||||
),
|
||||
self.env["account.move.line"],
|
||||
)
|
||||
self.assertEqual(
|
||||
aml.filtered(
|
||||
lambda ml: ml.product_id == self.component1
|
||||
and ml.account_id == account_expense
|
||||
and ml.account_id == self.account_expense
|
||||
),
|
||||
self.env["account.move.line"],
|
||||
)
|
||||
|
||||
def test_02_purchase_mrp_anglo_saxon(self):
|
||||
"""Test purchase order for kit, receive and invoice and ensure
|
||||
stock input account is hit
|
||||
"""
|
||||
# Create a PO for a specific partner for three units of the
|
||||
# finished product
|
||||
po_vals = {
|
||||
"partner_id": self.partner.id,
|
||||
"order_line": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": self.finished_product.name,
|
||||
"product_id": self.finished_product.id,
|
||||
"product_qty": 3,
|
||||
"product_uom": self.finished_product.uom_id.id,
|
||||
"price_unit": 100,
|
||||
},
|
||||
)
|
||||
],
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
self.po = self.env["purchase.order"].create(po_vals)
|
||||
# Validate the PO
|
||||
self.po.button_confirm()
|
||||
# Receive the three finished products
|
||||
pick = self.po.picking_ids
|
||||
# To check the products on the picking
|
||||
self.assertEqual(
|
||||
pick.move_line_ids.mapped("product_id"), self.component1 | self.component2
|
||||
)
|
||||
for ml in pick.move_line_ids:
|
||||
ml.qty_done = ml.reserved_uom_qty
|
||||
pick._action_done()
|
||||
# Create the invoice
|
||||
action = self.po.action_create_invoice()
|
||||
self.invoice = self.env["account.move"].browse(action["res_id"])
|
||||
self.invoice.invoice_date = self.invoice.date
|
||||
self.invoice.action_post()
|
||||
aml = self.invoice.line_ids
|
||||
aml_expense = aml.filtered(lambda l: l.account_id == self.account_expense)
|
||||
aml_input = aml.filtered(lambda l: l.account_id == self.account_input)
|
||||
# No line with expense account
|
||||
self.assertFalse(aml_expense)
|
||||
# Check that there is line with stock input account and amount:
|
||||
# 3*100 = 300
|
||||
self.assertEqual(
|
||||
sum(aml_input.mapped("debit")), 300, "GDNI missing or mismatching"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user