mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_quant_manual_assign: black, isort, prettier
This commit is contained in:
@@ -0,0 +1 @@
|
||||
../../../../stock_quant_manual_assign
|
||||
6
setup/stock_quant_manual_assign/setup.py
Normal file
6
setup/stock_quant_manual_assign/setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|
||||
@@ -14,13 +14,13 @@ Stock - Manual Quant Assignment
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/stock-logistics-warehouse/tree/12.0/stock_quant_manual_assign
|
||||
:target: https://github.com/OCA/stock-logistics-warehouse/tree/13.0/stock_quant_manual_assign
|
||||
:alt: OCA/stock-logistics-warehouse
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-12-0/stock-logistics-warehouse-12-0-stock_quant_manual_assign
|
||||
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-13-0/stock-logistics-warehouse-13-0-stock_quant_manual_assign
|
||||
:alt: Translate me on Weblate
|
||||
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
|
||||
:target: https://runbot.odoo-community.org/runbot/153/12.0
|
||||
:target: https://runbot.odoo-community.org/runbot/153/13.0
|
||||
:alt: Try me on Runbot
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
@@ -47,7 +47,7 @@ Bug Tracker
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us smashing it by providing a detailed and welcomed
|
||||
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_quant_manual_assign%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_quant_manual_assign%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Do not contact contributors directly about support or help with technical issues.
|
||||
|
||||
@@ -92,6 +92,6 @@ 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.
|
||||
|
||||
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/12.0/stock_quant_manual_assign>`_ project on GitHub.
|
||||
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/13.0/stock_quant_manual_assign>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||
|
||||
@@ -7,21 +7,16 @@
|
||||
|
||||
{
|
||||
"name": "Stock - Manual Quant Assignment",
|
||||
"version": "12.0.1.0.0",
|
||||
"version": "13.0.1.0.0",
|
||||
"category": "Warehouse",
|
||||
"license": "AGPL-3",
|
||||
"author": "AvanzOSC, "
|
||||
"Tecnativa, "
|
||||
"Eficent, "
|
||||
"Fanha Giang, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"Tecnativa, "
|
||||
"Eficent, "
|
||||
"Fanha Giang, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||
"depends": [
|
||||
"stock",
|
||||
],
|
||||
"data": [
|
||||
"wizard/assign_manual_quants_view.xml",
|
||||
"views/stock_move_view.xml",
|
||||
],
|
||||
"depends": ["stock"],
|
||||
"data": ["wizard/assign_manual_quants_view.xml", "views/stock_move_view.xml"],
|
||||
"installable": True,
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Project-Id-Version: Odoo Server 13.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
|
||||
@@ -367,7 +367,7 @@ ul.auto-toc {
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<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/stock-logistics-warehouse/tree/12.0/stock_quant_manual_assign"><img alt="OCA/stock-logistics-warehouse" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/stock-logistics-warehouse-12-0/stock-logistics-warehouse-12-0-stock_quant_manual_assign"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/153/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
|
||||
<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/stock-logistics-warehouse/tree/13.0/stock_quant_manual_assign"><img alt="OCA/stock-logistics-warehouse" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/stock-logistics-warehouse-13-0/stock-logistics-warehouse-13-0-stock_quant_manual_assign"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/153/13.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
|
||||
<p>This module allows you to manually change the automatic quant selection.</p>
|
||||
<p><strong>Table of contents</strong></p>
|
||||
<div class="contents local topic" id="contents">
|
||||
@@ -396,7 +396,7 @@ ul.auto-toc {
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/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 smashing it by providing a detailed and welcomed
|
||||
<a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_quant_manual_assign%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||
<a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_quant_manual_assign%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
@@ -436,7 +436,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
|
||||
<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>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/tree/12.0/stock_quant_manual_assign">OCA/stock-logistics-warehouse</a> project on GitHub.</p>
|
||||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/tree/13.0/stock_quant_manual_assign">OCA/stock-logistics-warehouse</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>
|
||||
</div>
|
||||
|
||||
@@ -1,112 +1,142 @@
|
||||
# Copyright 2015 Oihane Crucelaegui - AvanzOSC
|
||||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestStockQuantManualAssign(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestStockQuantManualAssign, self).setUp()
|
||||
self.quant_model = self.env['stock.quant']
|
||||
self.move_model = self.env['stock.move']
|
||||
self.quant_assign_wizard = self.env['assign.manual.quants']
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Product 4 test',
|
||||
'type': 'product',
|
||||
})
|
||||
self.location_src = self.env.ref(
|
||||
'stock.stock_location_locations_virtual')
|
||||
self.location_dst = self.env.ref('stock.stock_location_customers')
|
||||
self.location1 = self.env.ref('stock.location_inventory')
|
||||
self.location2 = self.env.ref('stock.location_procurement')
|
||||
self.location3 = self.env.ref('stock.location_production')
|
||||
self.quant1 = self.quant_model.sudo().create({
|
||||
'product_id': self.product.id,
|
||||
'quantity': 100.0,
|
||||
'location_id': self.location1.id,
|
||||
})
|
||||
self.quant2 = self.quant_model.sudo().create({
|
||||
'product_id': self.product.id,
|
||||
'quantity': 100.0,
|
||||
'location_id': self.location2.id,
|
||||
})
|
||||
self.quant3 = self.quant_model.sudo().create({
|
||||
'product_id': self.product.id,
|
||||
'quantity': 100.0,
|
||||
'location_id': self.location3.id,
|
||||
})
|
||||
self.move = self.move_model.create({
|
||||
'name': self.product.name,
|
||||
'product_id': self.product.id,
|
||||
'product_uom_qty': 400.0,
|
||||
'product_uom': self.product.uom_id.id,
|
||||
'location_id': self.location_src.id,
|
||||
'location_dest_id': self.location_dst.id,
|
||||
})
|
||||
self.quant_model = self.env["stock.quant"]
|
||||
self.move_model = self.env["stock.move"]
|
||||
self.quant_assign_wizard = self.env["assign.manual.quants"]
|
||||
self.product = self.env["product.product"].create(
|
||||
{"name": "Product 4 test", "type": "product"}
|
||||
)
|
||||
self.location_src = self.env.ref("stock.stock_location_locations_virtual")
|
||||
self.location_dst = self.env.ref("stock.stock_location_customers")
|
||||
self.location1 = self.env.ref("stock.location_inventory")
|
||||
self.location2 = self.env.ref("stock.location_procurement")
|
||||
self.location3 = self.env.ref("stock.location_production")
|
||||
self.quant1 = self.quant_model.sudo().create(
|
||||
{
|
||||
"product_id": self.product.id,
|
||||
"quantity": 100.0,
|
||||
"location_id": self.location1.id,
|
||||
}
|
||||
)
|
||||
self.quant2 = self.quant_model.sudo().create(
|
||||
{
|
||||
"product_id": self.product.id,
|
||||
"quantity": 100.0,
|
||||
"location_id": self.location2.id,
|
||||
}
|
||||
)
|
||||
self.quant3 = self.quant_model.sudo().create(
|
||||
{
|
||||
"product_id": self.product.id,
|
||||
"quantity": 100.0,
|
||||
"location_id": self.location3.id,
|
||||
}
|
||||
)
|
||||
self.move = self.move_model.create(
|
||||
{
|
||||
"name": self.product.name,
|
||||
"product_id": self.product.id,
|
||||
"product_uom_qty": 400.0,
|
||||
"product_uom": self.product.uom_id.id,
|
||||
"location_id": self.location_src.id,
|
||||
"location_dest_id": self.location_dst.id,
|
||||
}
|
||||
)
|
||||
self.move._action_confirm()
|
||||
|
||||
def test_quant_assign_wizard(self):
|
||||
wizard = self.quant_assign_wizard.with_context(
|
||||
active_id=self.move.id).create({
|
||||
})
|
||||
self.assertEqual(len(wizard.quants_lines.ids), 3,
|
||||
'Three quants created, three quants got by default')
|
||||
self.assertEqual(len(wizard.quants_lines.filtered('selected').ids), 0,
|
||||
'None of the quants must have been selected')
|
||||
self.assertEqual(wizard.lines_qty, 0.0,
|
||||
'None selected must give 0')
|
||||
self.assertEqual(sum(line.qty for line in wizard.quants_lines),
|
||||
self.move.reserved_availability)
|
||||
wizard = self.quant_assign_wizard.with_context(active_id=self.move.id).create(
|
||||
{}
|
||||
)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.ids),
|
||||
3,
|
||||
"Three quants created, three quants got by default",
|
||||
)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.filtered("selected").ids),
|
||||
0,
|
||||
"None of the quants must have been selected",
|
||||
)
|
||||
self.assertEqual(wizard.lines_qty, 0.0, "None selected must give 0")
|
||||
self.assertEqual(
|
||||
sum(line.qty for line in wizard.quants_lines),
|
||||
self.move.reserved_availability,
|
||||
)
|
||||
self.assertEqual(wizard.move_qty, self.move.product_uom_qty)
|
||||
|
||||
def test_quant_assign_wizard_constraint(self):
|
||||
wizard = self.quant_assign_wizard.with_context(
|
||||
active_id=self.move.id).create({
|
||||
})
|
||||
self.assertEqual(len(wizard.quants_lines.ids), 3,
|
||||
'Three quants created, three quants got by default')
|
||||
self.assertEqual(len(wizard.quants_lines.filtered('selected').ids), 0,
|
||||
'None of the quants must have been selected')
|
||||
self.assertEqual(wizard.lines_qty, 0.0,
|
||||
'None selected must give 0')
|
||||
wizard = self.quant_assign_wizard.with_context(active_id=self.move.id).create(
|
||||
{}
|
||||
)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.ids),
|
||||
3,
|
||||
"Three quants created, three quants got by default",
|
||||
)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.filtered("selected").ids),
|
||||
0,
|
||||
"None of the quants must have been selected",
|
||||
)
|
||||
self.assertEqual(wizard.lines_qty, 0.0, "None selected must give 0")
|
||||
with self.assertRaises(ValidationError):
|
||||
wizard.write({'quants_lines': [(1, wizard.quants_lines[:1].id,
|
||||
{'selected': True, 'qty': 500})]})
|
||||
wizard.write(
|
||||
{
|
||||
"quants_lines": [
|
||||
(1, wizard.quants_lines[:1].id, {"selected": True, "qty": 500})
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
def test_quant_manual_assign(self):
|
||||
wizard = self.quant_assign_wizard.with_context(
|
||||
active_id=self.move.id).create({
|
||||
})
|
||||
self.assertEqual(len(wizard.quants_lines.ids), 3,
|
||||
'Three quants created, three quants got by default')
|
||||
wizard.quants_lines[0].write({
|
||||
'selected': True,
|
||||
})
|
||||
wizard = self.quant_assign_wizard.with_context(active_id=self.move.id).create(
|
||||
{}
|
||||
)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.ids),
|
||||
3,
|
||||
"Three quants created, three quants got by default",
|
||||
)
|
||||
wizard.quants_lines[0].write({"selected": True})
|
||||
wizard.quants_lines[0]._onchange_selected()
|
||||
wizard.quants_lines[1].write({
|
||||
'selected': True,
|
||||
'qty': 50.0,
|
||||
})
|
||||
wizard.quants_lines[1].write({"selected": True, "qty": 50.0})
|
||||
self.assertEqual(wizard.lines_qty, 150.0)
|
||||
self.assertEqual(wizard.move_qty, 250.0)
|
||||
wizard.assign_quants()
|
||||
self.assertAlmostEqual(len(self.move.move_line_ids),
|
||||
len(wizard.quants_lines.filtered('selected')))
|
||||
self.assertAlmostEqual(
|
||||
len(self.move.move_line_ids), len(wizard.quants_lines.filtered("selected"))
|
||||
)
|
||||
|
||||
def test_quant_assign_wizard_after_availability_check(self):
|
||||
self.move._action_assign()
|
||||
wizard = self.quant_assign_wizard.with_context(
|
||||
active_id=self.move.id).create({
|
||||
})
|
||||
self.assertEqual(len(wizard.quants_lines.ids), 3,
|
||||
'Three quants created, three quants got by default')
|
||||
self.assertEqual(len(wizard.quants_lines.filtered('selected').ids), 3,
|
||||
'All the quants must have been selected')
|
||||
wizard = self.quant_assign_wizard.with_context(active_id=self.move.id).create(
|
||||
{}
|
||||
)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.ids),
|
||||
3,
|
||||
"Three quants created, three quants got by default",
|
||||
)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.filtered("selected").ids),
|
||||
3,
|
||||
"All the quants must have been selected",
|
||||
)
|
||||
self.assertEqual(wizard.lines_qty, 300.0)
|
||||
self.assertEqual(wizard.move_qty, 100.0)
|
||||
self.assertEqual(len(wizard.quants_lines.filtered('selected')),
|
||||
len(self.move.move_line_ids))
|
||||
self.assertEqual(sum(line.qty for line in wizard.quants_lines),
|
||||
self.move.reserved_availability)
|
||||
self.assertEqual(
|
||||
len(wizard.quants_lines.filtered("selected")), len(self.move.move_line_ids)
|
||||
)
|
||||
self.assertEqual(
|
||||
sum(line.qty for line in wizard.quants_lines),
|
||||
self.move.reserved_availability,
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="stock_picking_manual_quants_form_view">
|
||||
<field name="name">stock.picking.form</field>
|
||||
@@ -6,9 +6,14 @@
|
||||
<field name="inherit_id" ref="stock.view_picking_form" />
|
||||
<field name="arch" type="xml">
|
||||
<button name="action_show_details" position="before">
|
||||
<button name="%(assign_manual_quants_action)d" type="action" icon="fa-tags"
|
||||
string="Manual Quants" options='{"warn": true}'
|
||||
attrs="{'invisible':['|',('picking_code','=','incoming'),('state','not in',('confirmed','assigned','partially_available'))]}"/>
|
||||
<button
|
||||
name="%(assign_manual_quants_action)d"
|
||||
type="action"
|
||||
icon="fa-tags"
|
||||
string="Manual Quants"
|
||||
options='{"warn": true}'
|
||||
attrs="{'invisible':['|',('picking_code','=','incoming'),('state','not in',('confirmed','assigned','partially_available'))]}"
|
||||
/>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -6,45 +6,55 @@
|
||||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tools.float_utils import float_compare
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class AssignManualQuants(models.TransientModel):
|
||||
_name = 'assign.manual.quants'
|
||||
_name = "assign.manual.quants"
|
||||
_description = "Assign Manual Quants"
|
||||
|
||||
@api.multi
|
||||
@api.constrains('quants_lines')
|
||||
@api.constrains("quants_lines")
|
||||
def _check_qty(self):
|
||||
precision_digits = self.env[
|
||||
'decimal.precision'].precision_get('Product Unit of Measure')
|
||||
for record in self.filtered('quants_lines'):
|
||||
if float_compare(record.lines_qty, record.move_id.product_qty,
|
||||
precision_digits=precision_digits) > 0:
|
||||
raise ValidationError(
|
||||
_('Quantity is higher than the needed one'))
|
||||
precision_digits = self.env["decimal.precision"].precision_get(
|
||||
"Product Unit of Measure"
|
||||
)
|
||||
for record in self.filtered("quants_lines"):
|
||||
if (
|
||||
float_compare(
|
||||
record.lines_qty,
|
||||
record.move_id.product_qty,
|
||||
precision_digits=precision_digits,
|
||||
)
|
||||
> 0
|
||||
):
|
||||
raise ValidationError(_("Quantity is higher than the needed one"))
|
||||
|
||||
@api.depends('move_id', 'quants_lines', 'quants_lines.qty')
|
||||
@api.depends("move_id", "quants_lines", "quants_lines.qty")
|
||||
def _compute_qties(self):
|
||||
for record in self:
|
||||
record.lines_qty = sum(
|
||||
record.quants_lines.filtered('selected').mapped('qty')
|
||||
record.quants_lines.filtered("selected").mapped("qty")
|
||||
)
|
||||
record.move_qty = record.move_id.product_qty - record.lines_qty
|
||||
|
||||
lines_qty = fields.Float(
|
||||
string='Reserved qty', compute='_compute_qties',
|
||||
digits=dp.get_precision('Product Unit of Measure'))
|
||||
move_qty = fields.Float(string='Remaining qty', compute='_compute_qties',
|
||||
digits=dp.get_precision('Product Unit of Measure'))
|
||||
quants_lines = fields.One2many('assign.manual.quants.lines',
|
||||
'assign_wizard', string='Quants')
|
||||
move_id = fields.Many2one(
|
||||
comodel_name='stock.move',
|
||||
string='Move',
|
||||
string="Reserved qty",
|
||||
compute="_compute_qties",
|
||||
digits=dp.get_precision("Product Unit of Measure"),
|
||||
)
|
||||
move_qty = fields.Float(
|
||||
string="Remaining qty",
|
||||
compute="_compute_qties",
|
||||
digits=dp.get_precision("Product Unit of Measure"),
|
||||
)
|
||||
quants_lines = fields.One2many(
|
||||
"assign.manual.quants.lines", "assign_wizard", string="Quants"
|
||||
)
|
||||
move_id = fields.Many2one(comodel_name="stock.move", string="Move",)
|
||||
|
||||
@api.multi
|
||||
def assign_quants(self):
|
||||
@@ -56,90 +66,103 @@ class AssignManualQuants(models.TransientModel):
|
||||
for ml in move.move_line_ids:
|
||||
ml.qty_done = ml.product_qty
|
||||
move._recompute_state()
|
||||
move.mapped('picking_id')._compute_state()
|
||||
move.mapped("picking_id")._compute_state()
|
||||
return {}
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
res = super(AssignManualQuants, self).default_get(fields)
|
||||
move = self.env['stock.move'].browse(self.env.context['active_id'])
|
||||
available_quants = self.env['stock.quant'].search([
|
||||
('location_id', 'child_of', move.location_id.id),
|
||||
('product_id', '=', move.product_id.id),
|
||||
('quantity', '>', 0),
|
||||
])
|
||||
move = self.env["stock.move"].browse(self.env.context["active_id"])
|
||||
available_quants = self.env["stock.quant"].search(
|
||||
[
|
||||
("location_id", "child_of", move.location_id.id),
|
||||
("product_id", "=", move.product_id.id),
|
||||
("quantity", ">", 0),
|
||||
]
|
||||
)
|
||||
quants_lines = []
|
||||
for quant in available_quants:
|
||||
line = {}
|
||||
line['quant_id'] = quant.id
|
||||
line['on_hand'] = quant.quantity
|
||||
line['location_id'] = quant.location_id.id
|
||||
line['lot_id'] = quant.lot_id.id
|
||||
line['package_id'] = quant.package_id.id
|
||||
line['owner_id'] = quant.owner_id.id
|
||||
line['selected'] = False
|
||||
line["quant_id"] = quant.id
|
||||
line["on_hand"] = quant.quantity
|
||||
line["location_id"] = quant.location_id.id
|
||||
line["lot_id"] = quant.lot_id.id
|
||||
line["package_id"] = quant.package_id.id
|
||||
line["owner_id"] = quant.owner_id.id
|
||||
line["selected"] = False
|
||||
move_lines = move.move_line_ids.filtered(
|
||||
lambda ml: (ml.location_id == quant.location_id and
|
||||
ml.lot_id == quant.lot_id and
|
||||
ml.owner_id == quant.owner_id and
|
||||
ml.package_id == quant.package_id)
|
||||
lambda ml: (
|
||||
ml.location_id == quant.location_id
|
||||
and ml.lot_id == quant.lot_id
|
||||
and ml.owner_id == quant.owner_id
|
||||
and ml.package_id == quant.package_id
|
||||
)
|
||||
)
|
||||
line['qty'] = sum(move_lines.mapped('product_uom_qty'))
|
||||
line['selected'] = bool(line['qty'])
|
||||
line['reserved'] = quant.reserved_quantity - line['qty']
|
||||
line["qty"] = sum(move_lines.mapped("product_uom_qty"))
|
||||
line["selected"] = bool(line["qty"])
|
||||
line["reserved"] = quant.reserved_quantity - line["qty"]
|
||||
quants_lines.append(line)
|
||||
res.update({
|
||||
'quants_lines': [(0, 0, x) for x in quants_lines],
|
||||
'move_id': move.id,
|
||||
})
|
||||
res.update(
|
||||
{"quants_lines": [(0, 0, x) for x in quants_lines], "move_id": move.id}
|
||||
)
|
||||
return res
|
||||
|
||||
|
||||
class AssignManualQuantsLines(models.TransientModel):
|
||||
_name = 'assign.manual.quants.lines'
|
||||
_name = "assign.manual.quants.lines"
|
||||
_description = "Assign Manual Quants Lines"
|
||||
_rec_name = 'quant_id'
|
||||
_rec_name = "quant_id"
|
||||
|
||||
assign_wizard = fields.Many2one(
|
||||
comodel_name='assign.manual.quants', string='Move', required=True,
|
||||
ondelete='cascade')
|
||||
comodel_name="assign.manual.quants",
|
||||
string="Move",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
)
|
||||
quant_id = fields.Many2one(
|
||||
comodel_name='stock.quant', string='Quant', required=True,
|
||||
ondelete='cascade', oldname='quant')
|
||||
comodel_name="stock.quant",
|
||||
string="Quant",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
oldname="quant",
|
||||
)
|
||||
location_id = fields.Many2one(
|
||||
comodel_name='stock.location',
|
||||
string='Location',
|
||||
related='quant_id.location_id',
|
||||
groups="stock.group_stock_multi_locations"
|
||||
comodel_name="stock.location",
|
||||
string="Location",
|
||||
related="quant_id.location_id",
|
||||
groups="stock.group_stock_multi_locations",
|
||||
)
|
||||
lot_id = fields.Many2one(
|
||||
comodel_name='stock.production.lot', string='Lot',
|
||||
related='quant_id.lot_id',
|
||||
groups="stock.group_production_lot")
|
||||
comodel_name="stock.production.lot",
|
||||
string="Lot",
|
||||
related="quant_id.lot_id",
|
||||
groups="stock.group_production_lot",
|
||||
)
|
||||
package_id = fields.Many2one(
|
||||
comodel_name='stock.quant.package', string='Package',
|
||||
related='quant_id.package_id',
|
||||
groups="stock.group_tracking_lot")
|
||||
comodel_name="stock.quant.package",
|
||||
string="Package",
|
||||
related="quant_id.package_id",
|
||||
groups="stock.group_tracking_lot",
|
||||
)
|
||||
owner_id = fields.Many2one(
|
||||
comodel_name='res.partner',
|
||||
string='Owner',
|
||||
related='quant_id.owner_id',
|
||||
comodel_name="res.partner",
|
||||
string="Owner",
|
||||
related="quant_id.owner_id",
|
||||
groups="stock.group_tracking_owner",
|
||||
)
|
||||
# This is not correctly shown as related or computed, so we make it regular
|
||||
on_hand = fields.Float(
|
||||
readonly=True,
|
||||
string='On Hand',
|
||||
digits=dp.get_precision('Product Unit of Measure'),
|
||||
string="On Hand",
|
||||
digits=dp.get_precision("Product Unit of Measure"),
|
||||
)
|
||||
reserved = fields.Float(
|
||||
string='Others Reserved',
|
||||
digits=dp.get_precision('Product Unit of Measure'))
|
||||
selected = fields.Boolean(string='Select')
|
||||
qty = fields.Float(
|
||||
string='QTY', digits=dp.get_precision('Product Unit of Measure'))
|
||||
string="Others Reserved", digits=dp.get_precision("Product Unit of Measure")
|
||||
)
|
||||
selected = fields.Boolean(string="Select")
|
||||
qty = fields.Float(string="QTY", digits=dp.get_precision("Product Unit of Measure"))
|
||||
|
||||
@api.onchange('selected')
|
||||
@api.onchange("selected")
|
||||
def _onchange_selected(self):
|
||||
for record in self:
|
||||
if not record.selected:
|
||||
@@ -155,47 +178,66 @@ class AssignManualQuantsLines(models.TransientModel):
|
||||
record.qty = min(quant_qty, remaining_qty)
|
||||
|
||||
@api.multi
|
||||
@api.constrains('qty')
|
||||
@api.constrains("qty")
|
||||
def _check_qty(self):
|
||||
precision_digits = self.env[
|
||||
'decimal.precision'
|
||||
].precision_get('Product Unit of Measure')
|
||||
for record in self.filtered('qty'):
|
||||
precision_digits = self.env["decimal.precision"].precision_get(
|
||||
"Product Unit of Measure"
|
||||
)
|
||||
for record in self.filtered("qty"):
|
||||
quant = record.quant_id
|
||||
move_lines = record.assign_wizard.move_id.move_line_ids.filtered(
|
||||
lambda ml: (ml.location_id == quant.location_id and
|
||||
ml.lot_id == quant.lot_id)
|
||||
lambda ml: (
|
||||
ml.location_id == quant.location_id and ml.lot_id == quant.lot_id
|
||||
)
|
||||
)
|
||||
reserved = (
|
||||
quant.reserved_quantity - sum(
|
||||
move_lines.mapped('product_uom_qty'))
|
||||
reserved = quant.reserved_quantity - sum(
|
||||
move_lines.mapped("product_uom_qty")
|
||||
)
|
||||
if float_compare(record.qty, record.quant_id.quantity - reserved,
|
||||
precision_digits=precision_digits) > 0:
|
||||
if (
|
||||
float_compare(
|
||||
record.qty,
|
||||
record.quant_id.quantity - reserved,
|
||||
precision_digits=precision_digits,
|
||||
)
|
||||
> 0
|
||||
):
|
||||
raise ValidationError(
|
||||
_('Selected line quantity is higher than the available '
|
||||
'one. Maybe an operation with this product has been '
|
||||
'done meanwhile or you have manually increased the '
|
||||
'suggested value.')
|
||||
_(
|
||||
"Selected line quantity is higher than the available "
|
||||
"one. Maybe an operation with this product has been "
|
||||
"done meanwhile or you have manually increased the "
|
||||
"suggested value."
|
||||
)
|
||||
)
|
||||
|
||||
def _assign_quant_line(self):
|
||||
self.ensure_one()
|
||||
quant = self.env['stock.quant']
|
||||
precision_digits = self.env[
|
||||
'decimal.precision'].precision_get('Product Unit of Measure')
|
||||
quant = self.env["stock.quant"]
|
||||
precision_digits = self.env["decimal.precision"].precision_get(
|
||||
"Product Unit of Measure"
|
||||
)
|
||||
move = self.assign_wizard.move_id
|
||||
if float_compare(self.qty, 0.0, precision_digits=precision_digits) > 0:
|
||||
available_quantity = quant._get_available_quantity(
|
||||
move.product_id, self.location_id, lot_id=self.lot_id,
|
||||
package_id=self.package_id, owner_id=self.owner_id,
|
||||
move.product_id,
|
||||
self.location_id,
|
||||
lot_id=self.lot_id,
|
||||
package_id=self.package_id,
|
||||
owner_id=self.owner_id,
|
||||
)
|
||||
if float_compare(
|
||||
available_quantity, 0.0, precision_digits=precision_digits
|
||||
) <= 0:
|
||||
if (
|
||||
float_compare(
|
||||
available_quantity, 0.0, precision_digits=precision_digits
|
||||
)
|
||||
<= 0
|
||||
):
|
||||
return
|
||||
move._update_reserved_quantity(
|
||||
self.qty, available_quantity, self.location_id,
|
||||
lot_id=self.lot_id, package_id=self.package_id,
|
||||
owner_id=self.owner_id, strict=True
|
||||
self.qty,
|
||||
available_quantity,
|
||||
self.location_id,
|
||||
lot_id=self.lot_id,
|
||||
package_id=self.package_id,
|
||||
owner_id=self.owner_id,
|
||||
strict=True,
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="assign_manual_quants_form_view">
|
||||
<field name="name">assign.manual.quants.form</field>
|
||||
@@ -7,32 +7,48 @@
|
||||
<form>
|
||||
<field name='quants_lines' colspan="4">
|
||||
<tree editable="top" delete="0" create="0">
|
||||
<field name="lot_id"/>
|
||||
<field name="package_id"/>
|
||||
<field name="owner_id"/>
|
||||
<field name="location_id"/>
|
||||
<field name="on_hand"/>
|
||||
<field name="reserved"/>
|
||||
<field name="selected"/>
|
||||
<field name="qty" attrs="{'readonly':[('selected', '=', False)]}" sum="qty"/>
|
||||
<field name="lot_id" />
|
||||
<field name="package_id" />
|
||||
<field name="owner_id" />
|
||||
<field name="location_id" />
|
||||
<field name="on_hand" />
|
||||
<field name="reserved" />
|
||||
<field name="selected" />
|
||||
<field
|
||||
name="qty"
|
||||
attrs="{'readonly':[('selected', '=', False)]}"
|
||||
sum="qty"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
<group col='4' colspan="4">
|
||||
<field name="move_qty" colspan="2" readonly="1"/>
|
||||
<field name="move_qty" colspan="2" readonly="1" />
|
||||
<field name="lines_qty" invisible="1" />
|
||||
<field name="move_id" invisible="1"/>
|
||||
<field name="move_id" invisible="1" />
|
||||
</group>
|
||||
<footer>
|
||||
<button name="assign_quants" type="object"
|
||||
string="Confirm" class="oe_highlight" />
|
||||
<button name="cancel" string="Cancel" class="oe_link"
|
||||
special="cancel" />
|
||||
<button
|
||||
name="assign_quants"
|
||||
type="object"
|
||||
string="Confirm"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
<button
|
||||
name="cancel"
|
||||
string="Cancel"
|
||||
class="oe_link"
|
||||
special="cancel"
|
||||
/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window name="Manual assignment" res_model="assign.manual.quants"
|
||||
src_model="stock.move" view_mode="form" target="new"
|
||||
id="assign_manual_quants_action" />
|
||||
<act_window
|
||||
name="Manual assignment"
|
||||
res_model="assign.manual.quants"
|
||||
src_model="stock.move"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
id="assign_manual_quants_action"
|
||||
/>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user