mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
@@ -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"
|
||||
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user