mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
135 lines
5.6 KiB
Python
135 lines
5.6 KiB
Python
# Copyright (C) 2019 Akretion (http://www.akretion.com). All Rights Reserved
|
|
# @author David BEAL <david.beal@akretion.com>
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
import logging
|
|
from datetime import datetime
|
|
|
|
from odoo import _, models
|
|
from odoo.exceptions import UserError
|
|
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
MESSAGE = (
|
|
"Some of your components are tracked, you have to specify "
|
|
"a manufacturing order in order to retrieve the correct components."
|
|
)
|
|
ALTER_MESSAGE = (
|
|
"Alternatively, you may unbuild '%s' tracked product "
|
|
"if you set it as '%s'.\n"
|
|
"In this case lots'll be automatically created for you."
|
|
)
|
|
|
|
|
|
class MrpUnbuild(models.Model):
|
|
_inherit = "mrp.unbuild"
|
|
|
|
def action_unbuild(self):
|
|
""" We need to catch raise behavior when tracked products
|
|
are unbuild without an original manufacturing order and
|
|
go on with another workflow with
|
|
_bypass_tracked_product_without_mo()
|
|
"""
|
|
try:
|
|
res = super().action_unbuild()
|
|
except UserError as err:
|
|
# Unbuild is impossible because of MESSAGE
|
|
# original condition of this raise is :
|
|
# any(produce_move.has_tracking != 'none'
|
|
# and not self.mo_id for produce_move in produce_moves)
|
|
if hasattr(err, "name") and err.name == _(MESSAGE):
|
|
if self.product_id.allow_unbuild_purchased:
|
|
# In this case it becomes possible to unbuild
|
|
return self._bypass_tracked_product_without_mo()
|
|
# Here other option to resolve unbuild conditions
|
|
new_message = _(ALTER_MESSAGE) % (
|
|
self.product_id.name,
|
|
_("Unbuild Purchased"),
|
|
)
|
|
# We teach user the 2 conditions that make unbuild possible
|
|
raise UserError(_("%s \n\n%s") % (err.name, new_message))
|
|
# Here is the Odoo native raise
|
|
raise err
|
|
return res
|
|
|
|
def _bypass_tracked_product_without_mo(self):
|
|
# These moves are already generated with call to
|
|
# super().action_unbuild(). We catch them
|
|
consume_move = self.env["stock.move"].search(
|
|
[("consume_unbuild_id", "=", self.id)]
|
|
)
|
|
produce_moves = self.env["stock.move"].search([("unbuild_id", "=", self.id)])
|
|
|
|
# Comes from
|
|
# https://github.com/OCA/ocb/blob/12.0/addons/mrp/models/...
|
|
# mrp_unbuild.py#L117
|
|
if consume_move:
|
|
if consume_move.has_tracking != "none":
|
|
self.env["stock.move.line"].create(
|
|
{
|
|
"move_id": consume_move.id,
|
|
"lot_id": self.lot_id.id,
|
|
"qty_done": consume_move.product_uom_qty,
|
|
"product_id": consume_move.product_id.id,
|
|
"product_uom_id": consume_move.product_uom.id,
|
|
"location_id": consume_move.location_id.id,
|
|
"location_dest_id": consume_move.location_dest_id.id,
|
|
}
|
|
)
|
|
else:
|
|
consume_move.quantity_done = consume_move.product_uom_qty
|
|
consume_move._action_done()
|
|
|
|
# Comment from odoo original module:
|
|
# TODO: Will fail if user do more than one unbuild with lot
|
|
# on the same MO. Need to check what other unbuild has aready took
|
|
for produce_move in produce_moves:
|
|
if produce_move.has_tracking != "none":
|
|
if produce_move.product_id.tracking == "serial":
|
|
# TODO
|
|
raise UserError(
|
|
_(
|
|
"Unbuild of component of tracked as serial "
|
|
"is not supported for now: contact maintainers of "
|
|
"'mrp_unbuild_tracked_raw_material' module "
|
|
"if you want this feature"
|
|
)
|
|
)
|
|
lot = self.env["stock.production.lot"].create(
|
|
self._prepare_lots_for_purchased_unbuild(produce_move.product_id)
|
|
)
|
|
self.env["stock.move.line"].create(
|
|
{
|
|
"move_id": produce_move.id,
|
|
"lot_id": lot.id,
|
|
"qty_done": produce_move.product_uom_qty,
|
|
"product_id": produce_move.product_id.id,
|
|
"product_uom_id": produce_move.product_uom.id,
|
|
"location_id": produce_move.location_id.id,
|
|
"location_dest_id": produce_move.location_dest_id.id,
|
|
}
|
|
)
|
|
else:
|
|
produce_move.quantity_done = produce_move.product_uom_qty
|
|
# comes from native code
|
|
produce_moves._action_done()
|
|
produced_move_line_ids = produce_moves.mapped("move_line_ids").filtered(
|
|
lambda ml: ml.qty_done > 0
|
|
)
|
|
consume_move.move_line_ids.write(
|
|
{"produce_line_ids": [(6, 0, produced_move_line_ids.ids)]}
|
|
)
|
|
self.message_post(
|
|
body=_("Product has been unbuilt without previous manufacturing order")
|
|
)
|
|
return self.write({"state": "done"})
|
|
|
|
def _prepare_lots_for_purchased_unbuild(self, product):
|
|
# Customize your data lot with your own code
|
|
return {
|
|
"name": datetime.now().strftime(DT_FORMAT),
|
|
"product_id": product.id,
|
|
"company_id": self.env.company.id,
|
|
}
|