mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
@@ -76,6 +76,10 @@ Contributors
|
||||
|
||||
* Aung Ko Ko Lin
|
||||
|
||||
* `Tecnativa <https://www.tecnativa.com>`_:
|
||||
|
||||
* Víctor Martínez
|
||||
|
||||
Maintainers
|
||||
~~~~~~~~~~~
|
||||
|
||||
|
||||
50
mrp_subcontracting_skip_no_negative/i18n/es.po
Normal file
50
mrp_subcontracting_skip_no_negative/i18n/es.po
Normal 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."
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
* `Quartile <https://www.quartile.co>`__:
|
||||
|
||||
* Aung Ko Ko Lin
|
||||
|
||||
* `Tecnativa <https://www.tecnativa.com>`_:
|
||||
|
||||
* Víctor Martínez
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.assertEqual(subcontracting_receipt.state, "done")
|
||||
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(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")
|
||||
|
||||
Reference in New Issue
Block a user