Merge PR #1722 into 14.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2023-09-05 06:19:21 +00:00
7 changed files with 232 additions and 7 deletions

View File

@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-26 16:12+0000\n"
"PO-Revision-Date: 2023-01-26 17:12+0100\n"
"POT-Creation-Date: 2023-07-06 07:32+0000\n"
"PO-Revision-Date: 2023-07-06 09:32+0200\n"
"Last-Translator: Víctor Martínez <victor.martinez@tecnativa.com>\n"
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n"
"Language: es\n"
@@ -118,6 +118,11 @@ msgstr ""
"De manera predeterminada, solo se permiten ubicaciones internas y de "
"tránsito en Solicitud de inventario y pedidos."
#. module: stock_request
#: model_terms:ir.ui.view,arch_db:stock_request.res_config_settings_view_form
msgid "By default, available stock is not used"
msgstr "Por defecto, el stock disponible no se usa"
#. module: stock_request
#: model_terms:ir.ui.view,arch_db:stock_request.stock_request_order_form
#: model_terms:ir.ui.view,arch_db:stock_request.view_stock_request_form
@@ -137,6 +142,13 @@ msgstr "Cancelado"
msgid "Category"
msgstr "Categoría"
#. module: stock_request
#: model:ir.model.fields,field_description:stock_request.field_res_company__stock_request_check_available_first
#: model:ir.model.fields,field_description:stock_request.field_res_config_settings__stock_request_check_available_first
#: model_terms:ir.ui.view,arch_db:stock_request.res_config_settings_view_form
msgid "Check available stock first"
msgstr "Comprobar stock disponible primero"
#. module: stock_request
#: model_terms:ir.actions.act_window,help:stock_request.action_stock_request_form
msgid "Click to add a Stock Request."
@@ -179,6 +191,9 @@ msgid ""
"Conversion between Units of Measure can only occur if they belong to the "
"same category. The conversion will be made based on the ratios."
msgstr ""
"La conversión entre las unidades de medidas sólo pueden ocurrir si "
"pertenecen a la misma categoría. La conversión se basará en los ratios "
"establecidos."
#. module: stock_request
#: model:ir.model.fields,field_description:stock_request.field_stock_request__create_uid
@@ -531,7 +546,6 @@ msgstr "Nombre"
#. module: stock_request
#: model:ir.model.constraint,message:stock_request.constraint_stock_request_abstract_name_uniq
#: model:ir.model.constraint,message:stock_request.constraint_stock_request_kanban_name_uniq
msgid "Name must be unique"
msgstr "El nombre debe ser único"

View File

@@ -6,6 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-06 07:32+0000\n"
"PO-Revision-Date: 2023-07-06 07:32+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -107,6 +109,11 @@ msgid ""
"and Orders."
msgstr ""
#. module: stock_request
#: model_terms:ir.ui.view,arch_db:stock_request.res_config_settings_view_form
msgid "By default, available stock is not used"
msgstr ""
#. module: stock_request
#: model_terms:ir.ui.view,arch_db:stock_request.stock_request_order_form
#: model_terms:ir.ui.view,arch_db:stock_request.view_stock_request_form
@@ -126,6 +133,13 @@ msgstr ""
msgid "Category"
msgstr ""
#. module: stock_request
#: model:ir.model.fields,field_description:stock_request.field_res_company__stock_request_check_available_first
#: model:ir.model.fields,field_description:stock_request.field_res_config_settings__stock_request_check_available_first
#: model_terms:ir.ui.view,arch_db:stock_request.res_config_settings_view_form
msgid "Check available stock first"
msgstr ""
#. module: stock_request
#: model_terms:ir.actions.act_window,help:stock_request.action_stock_request_form
msgid "Click to add a Stock Request."
@@ -517,7 +531,6 @@ msgstr ""
#. module: stock_request
#: model:ir.model.constraint,message:stock_request.constraint_stock_request_abstract_name_uniq
#: model:ir.model.constraint,message:stock_request.constraint_stock_request_kanban_name_uniq
msgid "Name must be unique"
msgstr ""

View File

@@ -12,3 +12,6 @@ class ResCompany(models.Model):
stock_request_allow_virtual_loc = fields.Boolean(
string="Allow Virtual locations on Stock Requests"
)
stock_request_check_available_first = fields.Boolean(
string="Check available stock first"
)

View File

@@ -19,6 +19,9 @@ class ResConfigSettings(models.TransientModel):
string="Stock Requests Kanban integration"
)
stock_request_check_available_first = fields.Boolean(
related="company_id.stock_request_check_available_first", readonly=False
)
stock_request_allow_virtual_loc = fields.Boolean(
related="company_id.stock_request_allow_virtual_loc", readonly=False
)

View File

@@ -259,7 +259,7 @@ class StockRequest(models.Model):
def _action_confirm(self):
self._action_launch_procurement_rule()
self.write({"state": "open"})
self.filtered(lambda x: x.state != "done").write({"state": "open"})
def action_confirm(self):
self._action_confirm()
@@ -336,10 +336,50 @@ class StockRequest(models.Model):
def _skip_procurement(self):
return self.state != "draft" or self.product_id.type not in ("consu", "product")
def _prepare_stock_move(self, qty):
return {
"name": self.product_id.display_name,
"company_id": self.company_id.id,
"product_id": self.product_id.id,
"product_uom_qty": qty,
"product_uom": self.product_id.uom_id.id,
"location_id": self.location_id.id,
"location_dest_id": self.location_id.id,
"state": "draft",
"reference": self.name,
}
def _prepare_stock_request_allocation(self, move):
return {
"stock_request_id": self.id,
"stock_move_id": move.id,
"requested_product_uom_qty": move.product_uom_qty,
}
def _action_use_stock_available(self):
"""Create a stock move with the necessary data and mark it as done."""
allocation_model = self.env["stock.request.allocation"]
stock_move_model = self.env["stock.move"].sudo()
precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
quants = self.env["stock.quant"]._gather(self.product_id, self.location_id)
pending_qty = self.product_uom_qty
for quant in quants.filtered(lambda x: x.available_quantity >= 0):
qty_move = min(pending_qty, quant.available_quantity)
if float_compare(qty_move, 0, precision_digits=precision) > 0:
move = stock_move_model.create(self._prepare_stock_move(qty_move))
move._action_confirm()
pending_qty -= qty_move
# Create allocation + done move
allocation_model.create(self._prepare_stock_request_allocation(move))
move.quantity_done = move.product_uom_qty
move._action_done()
def _action_launch_procurement_rule(self):
"""
Launch procurement group run method with required/custom
fields genrated by a
Launch procurement group (if not enough stock is available) run method
with required/custom fields genrated by a
stock request. procurement group will launch '_run_move',
'_run_buy' or '_run_manufacture'
depending on the stock request product rule.
@@ -358,6 +398,21 @@ class StockRequest(models.Model):
if float_compare(qty, request.product_qty, precision_digits=precision) >= 0:
continue
# If stock is available we use it and we do not execute rule
if request.company_id.stock_request_check_available_first:
if (
float_compare(
request.product_id.sudo()
.with_context(location=request.location_id.id)
.qty_available,
request.product_uom_qty,
precision_digits=precision,
)
>= 0
):
request._action_use_stock_available()
continue
values = request._prepare_procurement_values(
group_id=request.procurement_group_id
)

View File

@@ -146,6 +146,11 @@ class TestStockRequestBase(TestStockRequest):
def setUp(self):
super().setUp()
def _create_stock_quant(self, product, location, qty):
self.env["stock.quant"].create(
{"product_id": product.id, "location_id": location.id, "quantity": qty}
)
def test_defaults(self):
vals = {
"product_id": self.product.id,
@@ -505,6 +510,124 @@ class TestStockRequestBase(TestStockRequest):
with self.assertRaises(exceptions.ValidationError):
self.request_order.with_user(self.stock_request_user).create(vals)
def test_stock_request_order_available_stock_01(self):
self.main_company.stock_request_check_available_first = True
self._create_stock_quant(self.product, self.warehouse.lot_stock_id, 6)
expected_date = fields.Datetime.now()
vals = {
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.warehouse.lot_stock_id.id,
"expected_date": expected_date,
"stock_request_ids": [
(
0,
0,
{
"product_id": self.product.id,
"product_uom_id": self.product.uom_id.id,
"product_uom_qty": 5.0,
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.warehouse.lot_stock_id.id,
"expected_date": expected_date,
},
)
],
}
order = self.request_order.with_user(self.stock_request_user).create(vals)
order.action_confirm()
self.assertEqual(order.stock_request_ids.state, "done")
self.assertEqual(order.state, "done")
self.assertEqual(len(order.stock_request_ids.move_ids), 1)
quant_stock = self.product.stock_quant_ids.filtered(
lambda x: x.location_id == self.warehouse.lot_stock_id
)
self.assertEqual(quant_stock.quantity, 6)
def test_stock_request_order_available_stock_02(self):
self.main_company.stock_request_check_available_first = True
self.location_child_1 = self._create_location(
name="Child 1",
location_id=self.warehouse.lot_stock_id.id,
company_id=self.main_company.id,
)
self.location_child_2 = self._create_location(
name="Child 2",
location_id=self.warehouse.lot_stock_id.id,
company_id=self.main_company.id,
)
self._create_stock_quant(self.product, self.location_child_1, 6)
expected_date = fields.Datetime.now()
vals = {
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.location_child_1.id,
"expected_date": expected_date,
"stock_request_ids": [
(
0,
0,
{
"product_id": self.product.id,
"product_uom_id": self.product.uom_id.id,
"product_uom_qty": 5.0,
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.location_child_1.id,
"expected_date": expected_date,
},
)
],
}
order = self.request_order.with_user(self.stock_request_user).create(vals)
order.action_confirm()
self.assertEqual(order.stock_request_ids.state, "done")
self.assertEqual(order.state, "done")
self.assertEqual(len(order.stock_request_ids.move_ids), 1)
def test_stock_request_order_available_stock_03(self):
self.main_company.stock_request_check_available_first = True
self.location_child_1 = self._create_location(
name="Child 1",
location_id=self.warehouse.lot_stock_id.id,
company_id=self.main_company.id,
)
self.location_child_2 = self._create_location(
name="Child 2",
location_id=self.warehouse.lot_stock_id.id,
company_id=self.main_company.id,
)
self._create_stock_quant(self.product, self.location_child_1, 3)
self._create_stock_quant(self.product, self.location_child_2, 2)
expected_date = fields.Datetime.now()
vals = {
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.warehouse.lot_stock_id.id,
"expected_date": expected_date,
"stock_request_ids": [
(
0,
0,
{
"product_id": self.product.id,
"product_uom_id": self.product.uom_id.id,
"product_uom_qty": 5.0,
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.warehouse.lot_stock_id.id,
"expected_date": expected_date,
},
)
],
}
order = self.request_order.with_user(self.stock_request_user).create(vals)
order.action_confirm()
self.assertEqual(order.stock_request_ids.state, "done")
self.assertEqual(order.state, "done")
self.assertEqual(len(order.stock_request_ids.move_ids), 2)
def test_stock_request_validations_01(self):
vals = {
"product_id": self.product.id,

View File

@@ -60,6 +60,20 @@
</div>
</div>
</div>
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="stock_request_check_available_first" />
</div>
<div class="o_setting_right_pane">
<label
string="Check available stock first"
for="stock_request_check_available_first"
/>
<div
class="text-muted"
>By default, available stock is not used</div>
</div>
</div>
</div>
<h2>Purchases</h2>
<div