summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2025-01-16 10:30:17 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2025-01-16 10:30:17 +0700
commit3d672f12eecd77af9a805cebd8ce3a7083957a1f (patch)
treeff079f6e18d9d38653aec79a55ef4f89778728a0 /indoteknik_custom/models
parent27f333cc14b8673b3c46e1969736d2fb60d9924f (diff)
wms push
Diffstat (limited to 'indoteknik_custom/models')
-rw-r--r--indoteknik_custom/models/stock_move.py4
-rw-r--r--indoteknik_custom/models/stock_picking.py234
2 files changed, 190 insertions, 48 deletions
diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py
index e1d4e74c..6b631713 100644
--- a/indoteknik_custom/models/stock_move.py
+++ b/indoteknik_custom/models/stock_move.py
@@ -12,9 +12,13 @@ class StockMove(models.Model):
default=lambda self: self.product_id.print_barcode,
)
qr_code_variant = fields.Binary("QR Code Variant", compute='_compute_qr_code_variant')
+ barcode = fields.Char(string='Barcode', related='product_id.barcode')
def _compute_qr_code_variant(self):
for rec in self:
+ if rec.picking_id.picking_type_code == 'outgoing' and rec.picking_id and rec.picking_id.origin and rec.picking_id.origin.startswith('SO/'):
+ rec.qr_code_variant = rec.product_id.qr_code_variant
+ rec.print_barcode = True
if rec.print_barcode and rec.print_barcode == True and rec.product_id and rec.product_id.qr_code_variant:
rec.qr_code_variant = rec.product_id.qr_code_variant
else:
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index cd330aeb..05a7ee4a 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -16,7 +16,8 @@ _logger = logging.getLogger(__name__)
class StockPicking(models.Model):
_inherit = 'stock.picking'
- # check_product_lines = fields.One2many('check.product', 'picking_id', string='Check Product', auto_join=True)
+ check_product_lines = fields.One2many('check.product', 'picking_id', string='Check Product', auto_join=True)
+ barcode_product_lines = fields.One2many('barcode.product', 'picking_id', string='Barcode Product', auto_join=True)
is_internal_use = fields.Boolean('Internal Use', help='flag which is internal use or not')
account_id = fields.Many2one('account.account', string='Account')
efaktur_id = fields.Many2one('vit.efaktur', string='Faktur Pajak')
@@ -176,7 +177,8 @@ class StockPicking(models.Model):
pickings = self.env['stock.picking'].search([
('picking_type_code', '=', 'outgoing'),
('state', '=', 'done'),
- ('carrier_id', '=', 9)
+ ('carrier_id', '=', 9),
+ ('lalamove_order_id', '!=', False)
])
for picking in pickings:
try:
@@ -810,7 +812,24 @@ class StockPicking(models.Model):
self.date_done = datetime.datetime.utcnow()
self.state_reserve = 'done'
return res
-
+
+
+ def check_qty_done_stock(self):
+ for line in self.move_line_ids_without_package:
+ def check_qty_per_inventory(self, product, location):
+ quant = self.env['stock.quant'].search([
+ ('product_id', '=', product.id),
+ ('location_id', '=', location.id),
+ ])
+
+ if quant:
+ return quant.quantity
+
+ return 0
+
+ qty_onhand = check_qty_per_inventory(self, line.product_id, line.location_id)
+ if line.qty_done > qty_onhand:
+ raise UserError('Quantity Done melebihi Quantity Onhand')
def send_mail_bills(self):
if self.picking_type_code == 'incoming' and self.purchase_id:
@@ -1008,48 +1027,167 @@ class StockPicking(models.Model):
return f'{formatted_fastest_eta} - {formatted_longest_eta}'
-# class CheckProduct(models.Model):
-# _name = 'check.product'
-# _description = 'Check Product'
-# _order = 'picking_id, id'
-
-# picking_id = fields.Many2one('stock.picking', string='Picking Reference', required=True, ondelete='cascade', index=True, copy=False)
-# product_id = fields.Many2one('product.product', string='Product')
-
-
-# @api.constrains('product_id')
-# def check_product_validity(self):
-# """
-# Validate if the product exists in the related stock.picking's move_ids_without_package
-# and ensure that the product's quantity does not exceed the available product_uom_qty.
-# """
-# for record in self:
-# if not record.picking_id or not record.product_id:
-# continue
-
-# # Filter move lines in the related picking for the selected product
-# moves = record.picking_id.move_ids_without_package.filtered(
-# lambda move: move.product_id.id == record.product_id.id
-# )
-
-# if not moves:
-# raise UserError((
-# "The product '%s' is not available in the related stock picking's moves. "
-# "Please check and try again."
-# ) % record.product_id.display_name)
-
-# # Calculate the total entries for the product in check.product for the same picking
-# product_entries_count = self.search_count([
-# ('picking_id', '=', record.picking_id.id),
-# ('product_id', '=', record.product_id.id)
-# ])
-
-# # Sum the product_uom_qty for all relevant moves
-# total_qty_in_moves = sum(moves.mapped('product_uom_qty'))
-
-# # Compare the count of entries against the available quantity
-# if product_entries_count > total_qty_in_moves:
-# raise UserError((
-# "The product '%s' exceeds the allowable quantity (%s) in the related stock picking's moves. "
-# "You can only add it %s times."
-# ) % (record.product_id.display_name, total_qty_in_moves, total_qty_in_moves))
+class CheckProduct(models.Model):
+ _name = 'check.product'
+ _description = 'Check Product'
+ _order = 'picking_id, id'
+
+ picking_id = fields.Many2one(
+ 'stock.picking',
+ string='Picking Reference',
+ required=True,
+ ondelete='cascade',
+ index=True,
+ copy=False,
+ )
+ product_id = fields.Many2one('product.product', string='Product', required=True)
+ quantity = fields.Float(string='Quantity', default=1.0, required=True)
+ status = fields.Char(string='Status', compute='_compute_status')
+
+ @api.depends('quantity')
+ def _compute_status(self):
+ for record in self:
+ moves = record.picking_id.move_ids_without_package.filtered(
+ lambda move: move.product_id.id == record.product_id.id
+ )
+ total_qty_in_moves = sum(moves.mapped('product_uom_qty'))
+
+ if record.quantity < total_qty_in_moves:
+ record.status = 'Pending'
+ else:
+ record.status = 'Done'
+
+
+ def create(self, vals):
+ # Create the record
+ record = super(CheckProduct, self).create(vals)
+ # Ensure uniqueness after creation
+ if not self.env.context.get('skip_consolidate'):
+ record.with_context(skip_consolidate=True)._consolidate_duplicate_lines()
+ return record
+
+ def write(self, vals):
+ # Write changes to the record
+ result = super(CheckProduct, self).write(vals)
+ # Ensure uniqueness after writing
+ if not self.env.context.get('skip_consolidate'):
+ self.with_context(skip_consolidate=True)._consolidate_duplicate_lines()
+ return result
+
+ def _sync_check_product_to_moves(self, picking):
+ """
+ Sinkronisasi quantity_done di move_ids_without_package
+ dengan total quantity dari check.product berdasarkan product_id.
+ """
+ for product_id in picking.check_product_lines.mapped('product_id'):
+ # Totalkan quantity dari semua baris check.product untuk product_id ini
+ total_quantity = sum(
+ line.quantity for line in picking.check_product_lines.filtered(lambda line: line.product_id == product_id)
+ )
+ # Update quantity_done di move yang relevan
+ moves = picking.move_ids_without_package.filtered(lambda move: move.product_id == product_id)
+ for move in moves:
+ move.quantity_done = total_quantity
+
+ def _consolidate_duplicate_lines(self):
+ """
+ Consolidate duplicate lines with the same product_id under the same picking_id
+ and sync the total quantity to related moves.
+ """
+ for picking in self.mapped('picking_id'):
+ lines_to_remove = self.env['check.product'] # Recordset untuk menyimpan baris yang akan dihapus
+ product_lines = picking.check_product_lines.filtered(lambda line: line.product_id)
+
+ # Group lines by product_id
+ product_groups = {}
+ for line in product_lines:
+ product_groups.setdefault(line.product_id.id, []).append(line)
+
+ for product_id, lines in product_groups.items():
+ if len(lines) > 1:
+ # Consolidate duplicate lines
+ first_line = lines[0]
+ total_quantity = sum(line.quantity for line in lines)
+
+ # Update the first line's quantity
+ first_line.with_context(skip_consolidate=True).write({'quantity': total_quantity})
+
+ # Add the remaining lines to the lines_to_remove recordset
+ lines_to_remove |= self.env['check.product'].browse([line.id for line in lines[1:]])
+
+ # Perform unlink after consolidation
+ if lines_to_remove:
+ lines_to_remove.unlink()
+
+ # Sync total quantities to moves
+ self._sync_check_product_to_moves(picking)
+
+ @api.onchange('product_id', 'quantity')
+ def check_product_validity(self):
+ for record in self:
+ if not record.picking_id or not record.product_id:
+ continue
+
+ # Filter moves related to the selected product
+ moves = record.picking_id.move_ids_without_package.filtered(
+ lambda move: move.product_id.id == record.product_id.id
+ )
+
+ if not moves:
+ raise UserError((
+ "The product '%s' is not available in the related stock picking's moves. "
+ "Please check and try again."
+ ) % record.product_id.display_name)
+
+ total_qty_in_moves = sum(moves.mapped('product_uom_qty'))
+
+ # Find existing lines for the same product, excluding the current line
+ existing_lines = record.picking_id.check_product_lines.filtered(
+ lambda line: line.product_id == record.product_id and line.id != record.id
+ )
+
+ if existing_lines:
+ # Get the first existing line
+ first_line = existing_lines[0]
+
+ # Calculate the total quantity after addition
+ total_quantity = sum(existing_lines.mapped('quantity')) - record.quantity
+
+ if total_quantity > total_qty_in_moves:
+ raise UserError((
+ "Quantity Product '%s' sudah melebihi quantity demand: (%s)."
+ ) % (record.product_id.display_name))
+
+ else:
+ # Check if the quantity exceeds the allowed total
+ if record.quantity > total_qty_in_moves:
+ raise UserError((
+ "Quantity Product '%s' sudah melebihi quantity demand: (%s)."
+ ) % (record.product_id.display_name))
+
+ # Set the quantity to the entered value
+ record.quantity = record.quantity
+
+class BarcodeProduct(models.Model):
+ _name = 'barcode.product'
+ _description = 'Barcode Product'
+ _order = 'picking_id, id'
+
+ picking_id = fields.Many2one(
+ 'stock.picking',
+ string='Picking Reference',
+ required=True,
+ ondelete='cascade',
+ index=True,
+ copy=False,
+ )
+ product_id = fields.Many2one('product.product', string='Product', required=True)
+ barcode = fields.Char(string='Barcode')
+
+ @api.constrains('barcode')
+ def send_barcode_to_product(self):
+ for record in self:
+ if record.barcode and not record.product_id.barcode:
+ record.product_id.barcode = record.barcode
+ else:
+ raise UserError('Barcode sudah terisi') \ No newline at end of file