mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_secondary_unit: black, isort
This commit is contained in:
committed by
Jesús Alan Ramos Rodríguez
parent
4452268bfc
commit
7ba30da3f9
@@ -1,24 +1,21 @@
|
||||
# Copyright 2018 Tecnativa - Sergio Teruel
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
{
|
||||
'name': 'Stock Secondary Unit',
|
||||
'summary': 'Get product quantities in a secondary unit',
|
||||
'version': '12.0.1.0.2',
|
||||
'development_status': 'Beta',
|
||||
'category': 'stock',
|
||||
'website': 'https://github.com/OCA/stock-logistics-warehouse',
|
||||
'author': 'Tecnativa, Odoo Community Association (OCA)',
|
||||
'license': 'AGPL-3',
|
||||
'application': False,
|
||||
'installable': True,
|
||||
'depends': [
|
||||
'stock',
|
||||
'product_secondary_unit',
|
||||
],
|
||||
'data': [
|
||||
'views/product_views.xml',
|
||||
'views/stock_move_views.xml',
|
||||
'views/stock_picking_views.xml',
|
||||
'report/report_deliveryslip.xml',
|
||||
"name": "Stock Secondary Unit",
|
||||
"summary": "Get product quantities in a secondary unit",
|
||||
"version": "13.0.1.0.2",
|
||||
"development_status": "Beta",
|
||||
"category": "stock",
|
||||
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||
"author": "Tecnativa, Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
"installable": True,
|
||||
"depends": ["stock", "product_secondary_unit"],
|
||||
"data": [
|
||||
"views/product_views.xml",
|
||||
"views/stock_move_views.xml",
|
||||
"views/stock_picking_views.xml",
|
||||
"report/report_deliveryslip.xml",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
# Copyright 2018 Tecnativa - Sergio Teruel
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.tools.float_utils import float_round
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class StockProductSecondaryUnit(models.AbstractModel):
|
||||
_name = 'stock.product.secondary.unit'
|
||||
_description = 'Stock Product Secondary Unit'
|
||||
_name = "stock.product.secondary.unit"
|
||||
_description = "Stock Product Secondary Unit"
|
||||
|
||||
secondary_unit_qty_available = fields.Float(
|
||||
string='Quantity On Hand (2Unit)',
|
||||
compute='_compute_secondary_unit_qty_available',
|
||||
digits=dp.get_precision('Product Unit of Measure'),
|
||||
string="Quantity On Hand (2Unit)",
|
||||
compute="_compute_secondary_unit_qty_available",
|
||||
digits=dp.get_precision("Product Unit of Measure"),
|
||||
)
|
||||
|
||||
def _compute_secondary_unit_qty_available(self):
|
||||
for product in self.filtered('stock_secondary_uom_id'):
|
||||
qty = product.qty_available / (
|
||||
product.stock_secondary_uom_id.factor or 1.0)
|
||||
for product in self.filtered("stock_secondary_uom_id"):
|
||||
qty = product.qty_available / (product.stock_secondary_uom_id.factor or 1.0)
|
||||
product.secondary_unit_qty_available = float_round(
|
||||
qty, precision_rounding=product.uom_id.rounding)
|
||||
qty, precision_rounding=product.uom_id.rounding
|
||||
)
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = ['product.template', 'stock.product.secondary.unit']
|
||||
_name = 'product.template'
|
||||
_inherit = ["product.template", "stock.product.secondary.unit"]
|
||||
_name = "product.template"
|
||||
|
||||
stock_secondary_uom_id = fields.Many2one(
|
||||
comodel_name='product.secondary.unit',
|
||||
string='Second unit for inventory',
|
||||
comodel_name="product.secondary.unit", string="Second unit for inventory"
|
||||
)
|
||||
|
||||
def _compute_quantities(self):
|
||||
@@ -38,8 +38,8 @@ class ProductTemplate(models.Model):
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
_inherit = ['product.product', 'stock.product.secondary.unit']
|
||||
_name = 'product.product'
|
||||
_inherit = ["product.product", "stock.product.secondary.unit"]
|
||||
_name = "product.product"
|
||||
|
||||
def _compute_quantities(self):
|
||||
super()._compute_quantities()
|
||||
|
||||
@@ -1,52 +1,49 @@
|
||||
# Copyright 2018 Tecnativa - Sergio Teruel
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.tools.float_utils import float_round
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class StockSecondaryUnitMixin(models.AbstractModel):
|
||||
_name = 'stock.secondary.unit.mixin'
|
||||
_description = 'Stock Secondary Unit Mixin'
|
||||
_name = "stock.secondary.unit.mixin"
|
||||
_description = "Stock Secondary Unit Mixin"
|
||||
|
||||
secondary_uom_id = fields.Many2one(
|
||||
comodel_name='product.secondary.unit',
|
||||
string='Second unit',
|
||||
comodel_name="product.secondary.unit", string="Second unit"
|
||||
)
|
||||
secondary_uom_qty = fields.Float(
|
||||
string='Secondary Qty',
|
||||
digits=dp.get_precision('Product Unit of Measure'),
|
||||
string="Secondary Qty", digits=dp.get_precision("Product Unit of Measure")
|
||||
)
|
||||
|
||||
|
||||
class StockMove(models.Model):
|
||||
_inherit = ['stock.move', 'stock.secondary.unit.mixin']
|
||||
_name = 'stock.move'
|
||||
_inherit = ["stock.move", "stock.secondary.unit.mixin"]
|
||||
_name = "stock.move"
|
||||
|
||||
def _merge_moves_fields(self):
|
||||
res = super(StockMove, self)._merge_moves_fields()
|
||||
res['secondary_uom_qty'] = self[-1:].secondary_uom_qty
|
||||
res["secondary_uom_qty"] = self[-1:].secondary_uom_qty
|
||||
return res
|
||||
|
||||
|
||||
class StockMoveLine(models.Model):
|
||||
_inherit = ['stock.move.line', 'stock.secondary.unit.mixin']
|
||||
_name = 'stock.move.line'
|
||||
_inherit = ["stock.move.line", "stock.secondary.unit.mixin"]
|
||||
_name = "stock.move.line"
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
move = self.env['stock.move'].browse(vals.get('move_id', False))
|
||||
move = self.env["stock.move"].browse(vals.get("move_id", False))
|
||||
if move.secondary_uom_id:
|
||||
uom = self.env['uom.uom'].browse(vals['product_uom_id'])
|
||||
uom = self.env["uom.uom"].browse(vals["product_uom_id"])
|
||||
factor = move.secondary_uom_id.factor * uom.factor
|
||||
move_line_qty = vals.get(
|
||||
'product_uom_qty', vals.get('qty_done', 0.0))
|
||||
move_line_qty = vals.get("product_uom_qty", vals.get("qty_done", 0.0))
|
||||
qty = float_round(
|
||||
move_line_qty / (factor or 1.0),
|
||||
precision_rounding=move.secondary_uom_id.uom_id.rounding
|
||||
precision_rounding=move.secondary_uom_id.uom_id.rounding,
|
||||
)
|
||||
vals.update(
|
||||
{"secondary_uom_qty": qty, "secondary_uom_id": move.secondary_uom_id.id}
|
||||
)
|
||||
vals.update({
|
||||
'secondary_uom_qty': qty,
|
||||
'secondary_uom_id': move.secondary_uom_id.id,
|
||||
})
|
||||
return super().create(vals)
|
||||
|
||||
@@ -10,94 +10,118 @@ class TestProductSecondaryUnit(SavepointCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.warehouse = cls.env.ref('stock.warehouse0')
|
||||
cls.product_uom_kg = cls.env.ref('uom.product_uom_kgm')
|
||||
cls.product_uom_unit = cls.env.ref('uom.product_uom_unit')
|
||||
ProductAttribute = cls.env['product.attribute']
|
||||
ProductAttributeValue = cls.env['product.attribute.value']
|
||||
cls.attribute_color = ProductAttribute.create({'name': 'test_color'})
|
||||
cls.attribute_value_white = ProductAttributeValue.create({
|
||||
'name': 'test_white',
|
||||
'attribute_id': cls.attribute_color.id,
|
||||
})
|
||||
cls.attribute_value_black = ProductAttributeValue.create({
|
||||
'name': 'test_black',
|
||||
'attribute_id': cls.attribute_color.id,
|
||||
})
|
||||
cls.product_template = cls.env['product.template'].create({
|
||||
'name': 'test',
|
||||
'uom_id': cls.product_uom_kg.id,
|
||||
'uom_po_id': cls.product_uom_kg.id,
|
||||
'type': 'product',
|
||||
'secondary_uom_ids': [
|
||||
(0, 0, {
|
||||
'code': 'A',
|
||||
'name': 'unit-700',
|
||||
'uom_id': cls.product_uom_unit.id,
|
||||
'factor': 0.5,
|
||||
}),
|
||||
(0, 0, {
|
||||
'code': 'B',
|
||||
'name': 'unit-900',
|
||||
'uom_id': cls.product_uom_unit.id,
|
||||
'factor': 0.9,
|
||||
}),
|
||||
],
|
||||
'attribute_line_ids': [(0, 0, {
|
||||
'attribute_id': cls.attribute_color.id,
|
||||
'value_ids': [(4, cls.attribute_value_white.id),
|
||||
(4, cls.attribute_value_black.id)],
|
||||
})],
|
||||
})
|
||||
secondary_unit = cls.env['product.secondary.unit'].search([
|
||||
('product_tmpl_id', '=', cls.product_template.id),
|
||||
], limit=1)
|
||||
cls.product_template.write({
|
||||
'sale_secondary_uom_id': secondary_unit.id,
|
||||
'stock_secondary_uom_id': secondary_unit.id,
|
||||
})
|
||||
StockQuant = cls.env['stock.quant']
|
||||
cls.quant_white = StockQuant.create({
|
||||
'product_id': cls.product_template.product_variant_ids[0].id,
|
||||
'location_id': cls.warehouse.lot_stock_id.id,
|
||||
'quantity': 10.0,
|
||||
})
|
||||
cls.quant_black = StockQuant.create({
|
||||
'product_id': cls.product_template.product_variant_ids[1].id,
|
||||
'location_id': cls.warehouse.lot_stock_id.id,
|
||||
'quantity': 10.0,
|
||||
})
|
||||
cls.warehouse = cls.env.ref("stock.warehouse0")
|
||||
cls.product_uom_kg = cls.env.ref("uom.product_uom_kgm")
|
||||
cls.product_uom_unit = cls.env.ref("uom.product_uom_unit")
|
||||
ProductAttribute = cls.env["product.attribute"]
|
||||
ProductAttributeValue = cls.env["product.attribute.value"]
|
||||
cls.attribute_color = ProductAttribute.create({"name": "test_color"})
|
||||
cls.attribute_value_white = ProductAttributeValue.create(
|
||||
{"name": "test_white", "attribute_id": cls.attribute_color.id}
|
||||
)
|
||||
cls.attribute_value_black = ProductAttributeValue.create(
|
||||
{"name": "test_black", "attribute_id": cls.attribute_color.id}
|
||||
)
|
||||
cls.product_template = cls.env["product.template"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"uom_id": cls.product_uom_kg.id,
|
||||
"uom_po_id": cls.product_uom_kg.id,
|
||||
"type": "product",
|
||||
"secondary_uom_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"code": "A",
|
||||
"name": "unit-700",
|
||||
"uom_id": cls.product_uom_unit.id,
|
||||
"factor": 0.5,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"code": "B",
|
||||
"name": "unit-900",
|
||||
"uom_id": cls.product_uom_unit.id,
|
||||
"factor": 0.9,
|
||||
},
|
||||
),
|
||||
],
|
||||
"attribute_line_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"attribute_id": cls.attribute_color.id,
|
||||
"value_ids": [
|
||||
(4, cls.attribute_value_white.id),
|
||||
(4, cls.attribute_value_black.id),
|
||||
],
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
secondary_unit = cls.env["product.secondary.unit"].search(
|
||||
[("product_tmpl_id", "=", cls.product_template.id)], limit=1
|
||||
)
|
||||
cls.product_template.write(
|
||||
{
|
||||
"sale_secondary_uom_id": secondary_unit.id,
|
||||
"stock_secondary_uom_id": secondary_unit.id,
|
||||
}
|
||||
)
|
||||
StockQuant = cls.env["stock.quant"]
|
||||
cls.quant_white = StockQuant.create(
|
||||
{
|
||||
"product_id": cls.product_template.product_variant_ids[0].id,
|
||||
"location_id": cls.warehouse.lot_stock_id.id,
|
||||
"quantity": 10.0,
|
||||
}
|
||||
)
|
||||
cls.quant_black = StockQuant.create(
|
||||
{
|
||||
"product_id": cls.product_template.product_variant_ids[1].id,
|
||||
"location_id": cls.warehouse.lot_stock_id.id,
|
||||
"quantity": 10.0,
|
||||
}
|
||||
)
|
||||
|
||||
def test_01_stock_secondary_unit_template(self):
|
||||
self.assertEqual(
|
||||
self.product_template.secondary_unit_qty_available, 40.0)
|
||||
self.assertEqual(self.product_template.secondary_unit_qty_available, 40.0)
|
||||
|
||||
def test_02_stock_secondary_unit_variant(self):
|
||||
for variant in self.product_template.product_variant_ids.filtered(
|
||||
'attribute_value_ids'):
|
||||
"attribute_value_ids"
|
||||
):
|
||||
self.assertEqual(variant.secondary_unit_qty_available, 20)
|
||||
|
||||
def test_03_stock_picking_secondary_unit(self):
|
||||
StockPicking = self.env['stock.picking']
|
||||
StockPicking = self.env["stock.picking"]
|
||||
product1 = self.product_template.product_variant_ids[0]
|
||||
location = self.env.ref('stock.stock_location_suppliers')
|
||||
location_dest = self.env.ref('stock.stock_location_stock')
|
||||
picking_type = self.env.ref('stock.picking_type_in')
|
||||
location = self.env.ref("stock.stock_location_suppliers")
|
||||
location_dest = self.env.ref("stock.stock_location_stock")
|
||||
picking_type = self.env.ref("stock.picking_type_in")
|
||||
move_vals = {
|
||||
'product_id': product1.id,
|
||||
'name': product1.display_name,
|
||||
'secondary_uom_id': product1.secondary_uom_ids[0].id,
|
||||
'product_uom': product1.uom_id.id,
|
||||
'product_uom_qty': 10.0,
|
||||
'location_id': location.id,
|
||||
'location_dest_id': location_dest.id,
|
||||
"product_id": product1.id,
|
||||
"name": product1.display_name,
|
||||
"secondary_uom_id": product1.secondary_uom_ids[0].id,
|
||||
"product_uom": product1.uom_id.id,
|
||||
"product_uom_qty": 10.0,
|
||||
"location_id": location.id,
|
||||
"location_dest_id": location_dest.id,
|
||||
}
|
||||
do_vals = {
|
||||
'location_id': location.id,
|
||||
'location_dest_id': location_dest.id,
|
||||
'picking_type_id': picking_type.id,
|
||||
'move_ids_without_package': [(0, None, move_vals),
|
||||
(0, None, move_vals)], # 2 moves
|
||||
"location_id": location.id,
|
||||
"location_dest_id": location_dest.id,
|
||||
"picking_type_id": picking_type.id,
|
||||
"move_ids_without_package": [
|
||||
(0, None, move_vals),
|
||||
(0, None, move_vals),
|
||||
], # 2 moves
|
||||
}
|
||||
delivery_order = StockPicking.create(do_vals)
|
||||
delivery_order.action_confirm()
|
||||
@@ -105,8 +129,9 @@ class TestProductSecondaryUnit(SavepointCase):
|
||||
self.assertEquals(len(delivery_order.move_lines), 1)
|
||||
self.assertEquals(len(delivery_order.move_line_ids), 1)
|
||||
# Qty merged to 20, and secondary unit qty is 40line
|
||||
uom_qty = sum(delivery_order.move_lines.mapped('product_uom_qty'))
|
||||
secondary_uom_qty = \
|
||||
sum(delivery_order.move_line_ids.mapped('secondary_uom_qty'))
|
||||
uom_qty = sum(delivery_order.move_lines.mapped("product_uom_qty"))
|
||||
secondary_uom_qty = sum(
|
||||
delivery_order.move_line_ids.mapped("secondary_uom_qty")
|
||||
)
|
||||
self.assertEquals(uom_qty, 20.0)
|
||||
self.assertEquals(secondary_uom_qty, 40.0)
|
||||
|
||||
Reference in New Issue
Block a user