summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/stock_move.py
diff options
context:
space:
mode:
Diffstat (limited to 'indoteknik_custom/models/stock_move.py')
-rw-r--r--indoteknik_custom/models/stock_move.py71
1 files changed, 69 insertions, 2 deletions
diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py
index cac88287..320c175f 100644
--- a/indoteknik_custom/models/stock_move.py
+++ b/indoteknik_custom/models/stock_move.py
@@ -2,6 +2,8 @@ from odoo import fields, models, api
from odoo.tools.misc import format_date, OrderedSet
from odoo.exceptions import UserError
import logging
+from odoo.tools.float_utils import float_compare, float_is_zero, float_round
+
_logger = logging.getLogger(__name__)
@@ -20,7 +22,6 @@ class StockMove(models.Model):
hold_outgoingg = fields.Boolean('Hold Outgoing', default=False)
product_image = fields.Binary(related="product_id.image_128", string="Product Image", readonly=True)
partial = fields.Boolean('Partial?', default=False)
-
# Ambil product uom dari SO line
@api.model
def create(self, vals):
@@ -28,7 +29,66 @@ class StockMove(models.Model):
sale_line = self.env['sale.order.line'].browse(vals['sale_line_id'])
vals['product_uom'] = sale_line.product_uom.id
return super().create(vals)
+
+ def _update_reserved_quantity(
+ self, need, available_quantity, location_id,
+ lot_id=None, package_id=None, owner_id=None, strict=True
+ ):
+ self.ensure_one()
+ picking = self.picking_id
+ if picking and 'BU/PICK' in (picking.name or ''):
+ _logger.info(f"[LocatorLogic] Running custom locator logic for {picking.name}")
+
+ # Ambil semua lokasi anak dari source location (ex: BU/Stock)
+ locations = self.env['stock.location'].search([
+ ('id', 'child_of', self.location_id.id),
+ ('usage', '=', 'internal'),
+ ('is_locked', '=', False),
+ # ('id', '!=', 57),
+ ], order='rack_level asc')
+
+ total_reserved = 0.0
+ remaining_need = need
+
+ for loc in locations:
+ if remaining_need <= 0:
+ break
+
+ quants = self.env['stock.quant']._gather(self.product_id, loc)
+ for quant in quants:
+ if quant.available_quantity <= 0:
+ continue
+
+ qty_to_take = min(quant.available_quantity, remaining_need)
+ _logger.info(
+ f"[LocatorLogic] Reserving {qty_to_take}/{remaining_need} "
+ f"from {loc.display_name} (avail={quant.available_quantity})"
+ )
+
+ reserved_now = super(StockMove, self)._update_reserved_quantity(
+ qty_to_take, quant.available_quantity, quant.location_id,
+ lot_id, package_id, owner_id, strict
+ )
+
+ total_reserved += reserved_now
+ remaining_need -= reserved_now
+
+ if remaining_need <= 0:
+ break
+
+ if total_reserved > 0:
+ _logger.info(f"[LocatorLogic] Total reserved: {total_reserved} / {need}")
+ return total_reserved
+ else:
+ _logger.info("[LocatorLogic] No available stock found in unlocked locations by level order.")
+ return 0
+
+ return super(StockMove, self)._update_reserved_quantity(
+ need, available_quantity, location_id, lot_id, package_id, owner_id, strict
+ )
+
+
# @api.model_create_multi
# def create(self, vals_list):
# moves = super(StockMove, self).create(vals_list)
@@ -288,4 +348,11 @@ class StockMoveLine(models.Model):
move = self.env['stock.move'].browse(vals['move_id'])
if move.product_uom:
vals['product_uom_id'] = move.product_uom.id
- return super().create(vals) \ No newline at end of file
+ return super().create(vals)
+ def _action_done(self):
+ for line in self:
+ if line.location_dest_id and line.location_dest_id.is_locked:
+ raise UserError(f"Lokasi '{line.location_dest_id.display_name}' sedang dikunci dan tidak bisa menerima barang.")
+ if line.location_id and line.location_id.is_locked:
+ raise UserError(f"Lokasi '{line.location_id.display_name}' sedang dikunci dan tidak bisa reserve barang.")
+ return super(StockMoveLine, self)._action_done()