Merge PR #1372 into 14.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2024-11-04 09:05:07 +00:00
7 changed files with 181 additions and 35 deletions

View File

@@ -76,6 +76,10 @@ Contributors
* Aung Ko Ko Lin
* `Tecnativa <https://www.tecnativa.com>`_:
* Víctor Martínez
Maintainers
~~~~~~~~~~~

View File

@@ -0,0 +1,50 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mrp_subcontracting_skip_no_negative
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 08:50+0000\n"
"PO-Revision-Date: 2024-11-04 09:51+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 3.0.1\n"
#. module: mrp_subcontracting_skip_no_negative
#: model:ir.model.fields,field_description:mrp_subcontracting_skip_no_negative.field_stock_move__display_name
msgid "Display Name"
msgstr "Nombre mostrado"
#. module: mrp_subcontracting_skip_no_negative
#: model:ir.model.fields,field_description:mrp_subcontracting_skip_no_negative.field_stock_move__id
msgid "ID"
msgstr "ID"
#. module: mrp_subcontracting_skip_no_negative
#: model:ir.model.fields,field_description:mrp_subcontracting_skip_no_negative.field_stock_move____last_update
msgid "Last Modified on"
msgstr "Última modificación el"
#. module: mrp_subcontracting_skip_no_negative
#: model:ir.model,name:mrp_subcontracting_skip_no_negative.model_stock_move
msgid "Stock Move"
msgstr "Movimiento de existencias"
#. module: mrp_subcontracting_skip_no_negative
#: code:addons/mrp_subcontracting_skip_no_negative/models/stock_move.py:0
#, python-format
msgid ""
"You cannot validate this stock operation because the stock level of the "
"component product '%s' would become negative (%s) on the stock location '%s' "
"and negative stock is not allowed for this product and/or location."
msgstr ""
"No se puede validar esta operación de stock porque el nivel de stock del "
"producto componente '%s' se volvería negativo (%s) en la ubicación de stock "
"'%s' y no se permite stock negativo para este producto y/o ubicación."

View File

@@ -6,6 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 08:50+0000\n"
"PO-Revision-Date: 2024-11-04 08:50+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -32,3 +34,12 @@ msgstr ""
#: model:ir.model,name:mrp_subcontracting_skip_no_negative.model_stock_move
msgid "Stock Move"
msgstr ""
#. module: mrp_subcontracting_skip_no_negative
#: code:addons/mrp_subcontracting_skip_no_negative/models/stock_move.py:0
#, python-format
msgid ""
"You cannot validate this stock operation because the stock level of the "
"component product '%s' would become negative (%s) on the stock location '%s'"
" and negative stock is not allowed for this product and/or location."
msgstr ""

View File

@@ -1,7 +1,10 @@
# Copyright 2023 Quartile Limited
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo import models
from odoo import _, models
from odoo.exceptions import ValidationError
from odoo.tools import config, float_compare
class StockMove(models.Model):
@@ -35,6 +38,41 @@ class StockMove(models.Model):
):
continue
moves_with_no_check -= move
# If you have not been able to allocate previously it is because there is
# no stock, therefore it will leave the stock negative, we deduct the
# quantity checking the components and show the corresponding error.
test_condition = (
config["test_enable"] and self.env.context.get("test_stock_no_negative")
) or not config["test_enable"]
if not test_condition:
continue
qty_precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
for p_move in unassigned_productions.move_raw_ids.filtered(
lambda x: x.state != "assigned"
and not x.product_id.allow_negative_stock
and not x.product_id.categ_id.allow_negative_stock
and not x.location_id.allow_negative_stock
):
product = p_move.product_id.sudo()
location = p_move.location_id
location_qty = product.with_context(location=location.id).free_qty
new_qty = location_qty - p_move.product_uom_qty
if float_compare(new_qty, 0, precision_digits=qty_precision) == -1:
raise ValidationError(
_(
"You cannot validate this stock operation because the "
"stock level of the component product '%s' would become "
"negative (%s) on the stock location '%s' and negative "
"stock is not allowed for this product and/or location."
)
% (
product.display_name,
new_qty,
location.complete_name,
)
)
res = super(StockMove, self - moves_with_no_check)._action_done(
cancel_backorder=cancel_backorder
)

View File

@@ -1,3 +1,7 @@
* `Quartile <https://www.quartile.co>`__:
* Aung Ko Ko Lin
* `Tecnativa <https://www.tecnativa.com>`_:
* Víctor Martínez

View File

@@ -8,11 +8,10 @@
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
@@ -275,7 +274,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +300,7 @@ span.option {
span.pre {
white-space: pre }
span.problematic, pre.problematic {
span.problematic {
color: red }
span.section-subtitle {
@@ -414,14 +413,16 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<li>Aung Ko Ko Lin</li>
</ul>
</li>
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Víctor Martínez</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h1>Maintainers</h1>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<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>

View File

@@ -1,8 +1,10 @@
# Copyright 2023 Quartile Limited
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo.exceptions import ValidationError
from odoo.tests import Form
from odoo.tools import mute_logger
from odoo.addons.mrp_subcontracting.tests.common import TestMrpSubcontractingCommon
@@ -17,40 +19,76 @@ class TestMrpSubcontractingSkipNoNegative(TestMrpSubcontractingCommon):
test_stock_no_negative=True,
)
)
def test_mrp_subcontracting_skip_no_negative(self):
picking_form = Form(self.env["stock.picking"])
picking_form.picking_type_id = self.env.ref("stock.picking_type_in")
picking_form.partner_id = self.subcontractor_partner1
picking_form = Form(cls.env["stock.picking"])
picking_form.picking_type_id = cls.env.ref("stock.picking_type_in")
picking_form.partner_id = cls.subcontractor_partner1
with picking_form.move_ids_without_package.new() as move:
move.product_id = self.finished
move.product_id = cls.finished
move.product_uom_qty = 1
subcontracting_receipt = picking_form.save()
subcontracting_receipt.action_confirm()
self.assertEqual(subcontracting_receipt.state, "assigned")
immediate_wizard = subcontracting_receipt.sudo().button_validate()
cls.subcontracting_receipt = picking_form.save()
def _create_stock_quant(self, product, qty):
self.env["stock.quant"].create(
{
"product_id": product.id,
"location_id": self.subcontractor_partner1.property_stock_subcontractor.id,
"quantity": qty,
}
)
@mute_logger("odoo.models.unlink")
def test_mrp_subcontracting_skip_no_negative_01(self):
self.subcontracting_receipt.action_confirm()
self.assertEqual(self.subcontracting_receipt.state, "assigned")
immediate_wizard = self.subcontracting_receipt.sudo().button_validate()
self.assertEqual(immediate_wizard.get("res_model"), "stock.immediate.transfer")
immediate_wizard_form = Form(
self.env[immediate_wizard["res_model"]].with_context(
**immediate_wizard["context"]
)
).save()
with self.assertRaises(ValidationError):
# Component1 error
with self.assertRaises(ValidationError) as e1:
immediate_wizard_form.process()
# Create component stock, and subcontracting receipt should now be successful.
self.env["stock.quant"].create(
{
"product_id": self.comp1.id,
"location_id": self.subcontractor_partner1.property_stock_subcontractor.id,
"quantity": 10,
}
)
self.env["stock.quant"].create(
{
"product_id": self.comp2.id,
"location_id": self.subcontractor_partner1.property_stock_subcontractor.id,
"quantity": 10,
}
)
self.assertIn("Component1", str(e1.exception))
# Create comp1 stock, and try subcontracting receipt process.
self._create_stock_quant(self.comp1, 10)
# Component2 error
with self.assertRaises(ValidationError) as e2:
immediate_wizard_form.process()
self.assertIn("Component2", str(e2.exception))
# Create comp2 stock, and subcontracting receipt should now be successful.
self._create_stock_quant(self.comp2, 10)
immediate_wizard_form.process()
self.assertEqual(subcontracting_receipt.state, "done")
self.assertEqual(self.subcontracting_receipt.state, "done")
def test_mrp_subcontracting_skip_no_negative_03(self):
self._create_stock_quant(self.comp1, 10)
self._create_stock_quant(self.comp2, 10)
self.subcontracting_receipt.action_confirm()
self.assertEqual(self.subcontracting_receipt.state, "assigned")
immediate_wizard = self.subcontracting_receipt.sudo().button_validate()
self.assertEqual(immediate_wizard.get("res_model"), "stock.immediate.transfer")
immediate_wizard_form = Form(
self.env[immediate_wizard["res_model"]].with_context(
**immediate_wizard["context"]
)
).save()
immediate_wizard_form.process()
self.assertEqual(self.subcontracting_receipt.state, "done")
def test_mrp_subcontracting_skip_no_negative_04(self):
self.subcontractor_partner1.property_stock_subcontractor.allow_negative_stock = (
True
)
self.subcontracting_receipt.action_confirm()
self.assertEqual(self.subcontracting_receipt.state, "assigned")
immediate_wizard = self.subcontracting_receipt.sudo().button_validate()
self.assertEqual(immediate_wizard.get("res_model"), "stock.immediate.transfer")
immediate_wizard_form = Form(
self.env[immediate_wizard["res_model"]].with_context(
**immediate_wizard["context"]
)
).save()
immediate_wizard_form.process()
self.assertEqual(self.subcontracting_receipt.state, "done")