[IMP] stock_picking_report_valued_sale_mrp: black, isort, prettier

This commit is contained in:
david
2021-05-06 16:26:53 +02:00
committed by Ernesto Tejeda
parent c05ea98509
commit 4960674641
5 changed files with 129 additions and 98 deletions

View File

@@ -10,11 +10,6 @@
"author": "Tecnativa, Odoo Community Association (OCA)",
"maintainers": ["chienandalu"],
"license": "AGPL-3",
"depends": [
"stock_picking_report_valued",
"sale_mrp",
],
"data": [
"report/stock_picking_report_valued.xml",
],
"depends": ["stock_picking_report_valued", "sale_mrp"],
"data": ["report/stock_picking_report_valued.xml"],
}

View File

@@ -4,7 +4,7 @@ from odoo import models
class StockMove(models.Model):
_inherit = 'stock.move'
_inherit = "stock.move"
def _get_components_per_kit(self):
"""Compute how many kit components were demanded from this line. We
@@ -16,13 +16,9 @@ class StockMove(models.Model):
return 0
component_demand = sum(
sale_line.move_ids.filtered(
lambda x: x.product_id == self.product_id and
not x.origin_returned_move_id and
(
x.state != "cancel" or (
x.state == "cancel" and x.backorder_id
)
)
lambda x: x.product_id == self.product_id
and not x.origin_returned_move_id
and (x.state != "cancel" or (x.state == "cancel" and x.backorder_id))
).mapped("product_uom_qty")
)
return component_demand / sale_line.product_uom_qty

View File

@@ -4,7 +4,7 @@ from odoo import api, fields, models
class StockMoveLine(models.Model):
_inherit = 'stock.move.line'
_inherit = "stock.move.line"
phantom_product_id = fields.Many2one(
comodel_name="product.product",
@@ -14,20 +14,18 @@ class StockMoveLine(models.Model):
readonly=True,
)
phantom_line = fields.Boolean(
compute="_compute_sale_order_line_fields",
compute_sudo=True,
compute="_compute_sale_order_line_fields", compute_sudo=True,
)
phantom_delivered_qty = fields.Float(
compute="_compute_sale_order_line_fields",
compute_sudo=True,
compute="_compute_sale_order_line_fields", compute_sudo=True,
)
@api.depends("sale_line")
def _compute_phantom_product_id(self):
"""Relate every line with its kit product"""
for line in self.filtered(
lambda x: x.sale_line and
x.sale_line.product_id._is_phantom_bom()):
lambda x: x.sale_line and x.sale_line.product_id._is_phantom_bom()
):
line.phantom_product_id = line.sale_line.product_id
def _compute_sale_order_line_fields(self):
@@ -37,8 +35,7 @@ class StockMoveLine(models.Model):
super()._compute_sale_order_line_fields()
kit_lines = self.filtered("phantom_product_id")
for sale_line in kit_lines.mapped("sale_line"):
move_lines = kit_lines.filtered(
lambda x: x.sale_line == sale_line)
move_lines = kit_lines.filtered(lambda x: x.sale_line == sale_line)
# Deduct the kit quantity from the first component in the picking.
# If the the kit is partially delivered, this could lead to an
# unacurate value.
@@ -47,42 +44,52 @@ class StockMoveLine(models.Model):
continue
price_unit = (
sale_line.price_subtotal / sale_line.product_uom_qty
if sale_line.product_uom_qty else sale_line.price_reduce)
if sale_line.product_uom_qty
else sale_line.price_reduce
)
# Compute how many kits were delivered from the components and
# the original demand. Note that if the qty is edited in the sale
# order this could lead to inconsitencies.
components_per_kit = phantom_line.move_id._get_components_per_kit()
phantom_line_qty_done = sum(move_lines.filtered(
lambda x: x.product_id == phantom_line.product_id
).mapped("qty_done"))
phantom_line_qty_done = sum(
move_lines.filtered(
lambda x: x.product_id == phantom_line.product_id
).mapped("qty_done")
)
quantity = phantom_line_qty_done / components_per_kit
taxes = phantom_line.sale_tax_id.compute_all(
price_unit=price_unit,
currency=phantom_line.currency_id,
quantity=quantity,
product=phantom_line.product_id,
partner=sale_line.order_id.partner_shipping_id)
partner=sale_line.order_id.partner_shipping_id,
)
if sale_line.company_id.tax_calculation_rounding_method == (
'round_globally'):
price_tax = sum(
t.get('amount', 0.0) for t in taxes.get('taxes', []))
"round_globally"
):
price_tax = sum(t.get("amount", 0.0) for t in taxes.get("taxes", []))
else:
price_tax = taxes['total_included'] - taxes['total_excluded']
phantom_line.update({
'sale_tax_description': ', '.join(
t.name or t.description for t in phantom_line.sale_tax_id),
'sale_price_subtotal': taxes['total_excluded'],
'sale_price_tax': price_tax,
'sale_price_total': taxes['total_included'],
'phantom_line': True,
'phantom_delivered_qty': quantity,
})
price_tax = taxes["total_included"] - taxes["total_excluded"]
phantom_line.update(
{
"sale_tax_description": ", ".join(
t.name or t.description for t in phantom_line.sale_tax_id
),
"sale_price_subtotal": taxes["total_excluded"],
"sale_price_tax": price_tax,
"sale_price_total": taxes["total_included"],
"phantom_line": True,
"phantom_delivered_qty": quantity,
}
)
# Remove the other lines
redundant_lines = move_lines[1:]
if redundant_lines:
redundant_lines.update({
'sale_tax_description': '',
'sale_price_subtotal': 0,
'sale_price_tax': 0,
'sale_price_total': 0,
})
redundant_lines.update(
{
"sale_tax_description": "",
"sale_price_subtotal": 0,
"sale_price_tax": 0,
"sale_price_total": 0,
}
)

View File

@@ -1,48 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="valued_report_picking" inherit_id="stock_picking_report_valued.valued_report_picking">
<xpath expr="//t[@t-if=&quot;move_line.picking_id.state != 'done'&quot;]/.." position="attributes">
<attribute name="t-if">o.valued and o.sale_id and o.move_line_ids and (move_line.phantom_line or not move_line.phantom_product_id)</attribute>
<template
id="valued_report_picking"
inherit_id="stock_picking_report_valued.valued_report_picking"
>
<xpath
expr="//t[@t-if=&quot;move_line.picking_id.state != 'done'&quot;]/.."
position="attributes"
>
<attribute
name="t-if"
>o.valued and o.sale_id and o.move_line_ids and (move_line.phantom_line or not move_line.phantom_product_id)</attribute>
</xpath>
<xpath expr="//tr[@t-foreach='o.move_line_ids']" position="attributes">
<attribute name="t-foreach">o.move_line_ids.filtered(lambda x: not x.phantom_product_id or x.phantom_line)</attribute>
<attribute
name="t-foreach"
>o.move_line_ids.filtered(lambda x: not x.phantom_product_id or x.phantom_line)</attribute>
</xpath>
<xpath expr="//span[@t-field='move_line.product_id']" position="attributes">
<attribute name="t-if">not move_line.phantom_line</attribute>
</xpath>
<xpath expr="//span[@t-field='move_line.product_id']" position="before">
<span t-field="move_line.sale_line.product_id" t-if="move_line.phantom_line"/>
<span
t-field="move_line.sale_line.product_id"
t-if="move_line.phantom_line"
/>
</xpath>
<xpath expr="//span[@t-field='move_line.product_id.sudo().description_pickingout']" position="attributes">
<xpath
expr="//span[@t-field='move_line.product_id.sudo().description_pickingout']"
position="attributes"
>
<attribute name="t-if">not move_line.phantom_line</attribute>
</xpath>
<xpath expr="//span[@t-field='move_line.product_id.sudo().description_pickingout']" position="before">
<span t-field="move_line.sale_line.product_id.sudo().description_pickingout" t-if="move_line.phantom_line"/>
<xpath
expr="//span[@t-field='move_line.product_id.sudo().description_pickingout']"
position="before"
>
<span
t-field="move_line.sale_line.product_id.sudo().description_pickingout"
t-if="move_line.phantom_line"
/>
</xpath>
<xpath expr="//span[@t-field='move_line.qty_done']/.." position="attributes">
<attribute name="t-if">not move_line.phantom_line</attribute>
</xpath>
<xpath expr="//span[@t-field='move_line.qty_done']/.." position="after">
<td class="text-center" t-if="move_line.phantom_line">
<span t-field="move_line.phantom_delivered_qty"/>
<span t-field="move_line.sale_line.product_uom"/>
</td>
<span t-field="move_line.phantom_delivered_qty" />
<span t-field="move_line.sale_line.product_uom" />
</td>
</xpath>
<xpath expr="//span[@t-field='move_line.lot_id.name']" position="attributes">
<attribute name="t-if">not move_line.phantom_line</attribute>
</xpath>
<xpath expr="//span[@t-field='move_line.lot_id.name']" position="after">
<t t-set="kit_move_lines" t-value="move_line.sale_line.mapped('move_ids.move_line_ids').filtered(lambda x: x.sale_line == move_line.sale_line)" />
<t
t-set="kit_move_lines"
t-value="move_line.sale_line.mapped('move_ids.move_line_ids').filtered(lambda x: x.sale_line == move_line.sale_line)"
/>
<t t-if="kit_move_lines and move_line.phantom_line">
<table class="table-borderless">
<t t-foreach="kit_move_lines.mapped('product_id')" t-as="kit_component">
<t
t-foreach="kit_move_lines.mapped('product_id')"
t-as="kit_component"
>
<small class="font-italic" t-esc="kit_component.display_name" />
<t t-if="kit_move_lines.mapped('lot_id')">
<span class="font-italic">: </span>
</t>
<small t-esc="', '.join([k.lot_id.name for k in kit_move_lines.filtered(lambda x: x.lot_id and x.product_id == kit_component)])" />
<br/>
<small
t-esc="', '.join([k.lot_id.name for k in kit_move_lines.filtered(lambda x: x.lot_id and x.product_id == kit_component)])"
/>
<br />
</t>
</table>
</t>

View File

@@ -1,11 +1,12 @@
# Copyright 2020 Tecnativa - David Vidal
from odoo.addons.stock_picking_report_valued.tests\
.test_stock_picking_valued import TestStockPickingValued
from odoo.tests import Form
from odoo.addons.stock_picking_report_valued.tests.test_stock_picking_valued import (
TestStockPickingValued,
)
class TestStockPickingValuedMrp(TestStockPickingValued):
@classmethod
def setUpClass(cls):
"""We want to run parent class tests again to ensure everything
@@ -13,36 +14,37 @@ class TestStockPickingValuedMrp(TestStockPickingValued):
super().setUpClass()
cls.res_partner = cls.env["res.partner"]
cls.product_product = cls.env["product.product"]
cls.product_kit = cls.product_product.create({
"name": "Product test 1",
"type": "consu",
})
cls.product_kit_comp_1 = cls.product_product.create({
"name": "Product Component 1",
"type": "product",
})
cls.product_kit_comp_2 = cls.product_product.create({
"name": "Product Component 2",
"type": "product",
})
cls.bom = cls.env["mrp.bom"].create({
"product_id": cls.product_kit.id,
"product_tmpl_id": cls.product_kit.product_tmpl_id.id,
"type": "phantom",
"bom_line_ids": [
(0, 0, {
"product_id": cls.product_kit_comp_1.id,
"product_qty": 2,
}),
(0, 0, {
"product_id": cls.product_kit_comp_2.id,
"product_qty": 4,
})
]})
cls.product_2 = cls.product_product.create({
"name": "Product test 2",
"type": "product",
})
cls.product_kit = cls.product_product.create(
{"name": "Product test 1", "type": "consu"}
)
cls.product_kit_comp_1 = cls.product_product.create(
{"name": "Product Component 1", "type": "product"}
)
cls.product_kit_comp_2 = cls.product_product.create(
{"name": "Product Component 2", "type": "product"}
)
cls.bom = cls.env["mrp.bom"].create(
{
"product_id": cls.product_kit.id,
"product_tmpl_id": cls.product_kit.product_tmpl_id.id,
"type": "phantom",
"bom_line_ids": [
(
0,
0,
{"product_id": cls.product_kit_comp_1.id, "product_qty": 2},
),
(
0,
0,
{"product_id": cls.product_kit_comp_2.id, "product_qty": 4},
),
],
}
)
cls.product_2 = cls.product_product.create(
{"name": "Product test 2", "type": "product"}
)
order_form = Form(cls.env["sale.order"])
order_form.partner_id = cls.partner
with order_form.order_line.new() as line_form:
@@ -56,7 +58,8 @@ class TestStockPickingValuedMrp(TestStockPickingValued):
# Maybe other modules create additional lines in the create
# method in sale.order model, so let's find the correct line.
cls.order_line = cls.sale_order_3.order_line.filtered(
lambda r: r.product_id == cls.product_kit)
lambda r: r.product_id == cls.product_kit
)
cls.order_out_picking = cls.sale_order_3.picking_ids
def test_01_picking_confirmed(self):