[IMP] stock_secondary_unit: black, isort

This commit is contained in:
ps-tubtim
2019-12-18 10:59:51 +07:00
committed by Jesús Alan Ramos Rodríguez
parent 4452268bfc
commit 7ba30da3f9
4 changed files with 154 additions and 135 deletions

View File

@@ -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",
],
}

View File

@@ -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()

View File

@@ -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)

View File

@@ -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)