diff options
| author | Miqdad <ahmadmiqdad27@gmail.com> | 2025-07-17 13:17:15 +0700 |
|---|---|---|
| committer | Miqdad <ahmadmiqdad27@gmail.com> | 2025-07-17 13:17:15 +0700 |
| commit | 3c7d7783aa15fee124d94839822614de4049b9c1 (patch) | |
| tree | 88564154a3ed1b7e72fa732c4fa10109e4151818 | |
| parent | 2c5f2513e9380da52d9893c8dc5ad148c298a882 (diff) | |
<miqdad> Done Tukar Guling SO
| -rw-r--r-- | indoteknik_custom/models/tukar_guling.py | 137 |
1 files changed, 91 insertions, 46 deletions
diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py index 295ca5d9..ded4e2a3 100644 --- a/indoteknik_custom/models/tukar_guling.py +++ b/indoteknik_custom/models/tukar_guling.py @@ -477,6 +477,7 @@ class TukarGuling(models.Model): self.state = 'cancel' def _create_pickings(self): + _logger.info("🛠 Starting _create_pickings()") for record in self: if not record.operations: raise UserError("BU/OUT dari field operations tidak ditemukan.") @@ -484,141 +485,185 @@ class TukarGuling(models.Model): bu_out = record.operations mapping_koli = record.mapping_koli_ids + # Constants + PARTNER_LOCATION_ID = 5 + BU_OUTPUT_LOCATION_ID = 60 + BU_STOCK_LOCATION_ID = 57 + + # Picking Types srt_type = self.env['stock.picking.type'].browse(73) ort_type = self.env['stock.picking.type'].browse(74) bu_pick_type = self.env['stock.picking.type'].browse(30) bu_out_type = self.env['stock.picking.type'].browse(29) - PARTNER_LOCATION_ID = 5 - BU_OUTPUT_LOCATION_ID = 60 - BU_STOCK_LOCATION_ID = 57 - created_returns = [] - ### ============= SRT dari BU/OUT ================== + ### ======== SRT dari BU/OUT ========= srt_return_lines = [] for prod in mapping_koli.mapped('product_id'): - qty_total_return = sum(mk.qty_return for mk in mapping_koli.filtered(lambda m: m.product_id == prod)) + qty_total = sum(mk.qty_return for mk in mapping_koli.filtered(lambda m: m.product_id == prod)) move = bu_out.move_lines.filtered(lambda m: m.product_id == prod) if not move: - raise UserError(f"Tidak ditemukan move BU/OUT untuk product {prod.display_name}") + raise UserError(f"Move BU/OUT tidak ditemukan untuk produk {prod.display_name}") srt_return_lines.append((0, 0, { 'product_id': prod.id, - 'quantity': qty_total_return, - 'move_id': move[0].id, + 'quantity': qty_total, + 'move_id': move.id, })) + _logger.info(f"📟 SRT line: {prod.display_name} | qty={qty_total}") srt_picking = None if srt_return_lines: - srt_context = { + srt_wizard = self.env['stock.return.picking'].with_context({ 'active_id': bu_out.id, 'default_location_id': PARTNER_LOCATION_ID, 'default_location_dest_id': BU_OUTPUT_LOCATION_ID, 'from_ui': False, - } - srt_wizard = self.env['stock.return.picking'].with_context(srt_context).create({ + }).create({ 'picking_id': bu_out.id, - 'location_id': BU_OUTPUT_LOCATION_ID, - 'original_location_id': PARTNER_LOCATION_ID, + 'location_id': PARTNER_LOCATION_ID, + 'original_location_id': BU_OUTPUT_LOCATION_ID, 'product_return_moves': srt_return_lines }) srt_vals = srt_wizard.create_returns() - srt_picking = self.env['stock.picking'].browse(srt_vals.get('res_id')) + srt_picking = self.env['stock.picking'].browse(srt_vals['res_id']) srt_picking.write({ 'location_id': PARTNER_LOCATION_ID, 'location_dest_id': BU_OUTPUT_LOCATION_ID, 'group_id': bu_out.group_id.id, 'tukar_guling_id': record.id, + 'sale_order': record.origin }) created_returns.append(srt_picking) + _logger.info(f"✅ SRT created: {srt_picking.name}") - ### ============= ORT dari BU/PICK ================== + ### ======== ORT dari BU/PICK ========= ort_pickings = [] for pick in mapping_koli.mapped('pick_id'): ort_return_lines = [] - pick_lines = mapping_koli.filtered(lambda m: m.pick_id == pick) - for mk in pick_lines: + for mk in mapping_koli.filtered(lambda m: m.pick_id == pick): move = pick.move_lines.filtered(lambda m: m.product_id == mk.product_id) if not move: raise UserError( - f"Tidak ditemukan move di BU/PICK {pick.name} untuk {mk.product_id.display_name}") + f"Move tidak ditemukan di BU/PICK {pick.name} untuk {mk.product_id.display_name}") ort_return_lines.append((0, 0, { 'product_id': mk.product_id.id, 'quantity': mk.qty_return, - 'move_id': move[0].id + 'move_id': move.id, })) + _logger.info(f"📟 ORT line: {pick.name} | {mk.product_id.display_name} | qty={mk.qty_return}") + if ort_return_lines: - ort_context = { + ort_wizard = self.env['stock.return.picking'].with_context({ 'active_id': pick.id, - 'default_location_id': BU_STOCK_LOCATION_ID, - 'default_location_dest_id': BU_OUTPUT_LOCATION_ID, + 'default_location_id': BU_OUTPUT_LOCATION_ID, + 'default_location_dest_id': BU_STOCK_LOCATION_ID, 'from_ui': False, - } - ort_wizard = self.env['stock.return.picking'].with_context(ort_context).create({ + }).create({ 'picking_id': pick.id, 'location_id': BU_OUTPUT_LOCATION_ID, 'original_location_id': BU_STOCK_LOCATION_ID, 'product_return_moves': ort_return_lines }) ort_vals = ort_wizard.create_returns() - ort_picking = self.env['stock.picking'].browse(ort_vals.get('res_id')) + ort_picking = self.env['stock.picking'].browse(ort_vals['res_id']) ort_picking.write({ - 'location_id': BU_STOCK_LOCATION_ID, - 'location_dest_id': BU_OUTPUT_LOCATION_ID, + 'location_id': BU_OUTPUT_LOCATION_ID, + 'location_dest_id': BU_STOCK_LOCATION_ID, 'group_id': bu_out.group_id.id, 'tukar_guling_id': record.id, + 'sale_order': record.origin }) - ort_pickings.append(ort_picking) created_returns.append(ort_picking) + ort_pickings.append(ort_picking) + _logger.info(f"✅ ORT created: {ort_picking.name}") - ### ============= BU/PICK & BU/OUT baru (tukar guling) ============== + ### ======== Tukar Guling: BU/OUT dan BU/PICK baru ======== if record.return_type == 'tukar_guling': - # Dari SRT → BU/OUT baru + # BU/OUT Baru dari SRT if srt_picking: - bu_out_new = self.env['stock.return.picking'].with_context({ + return_lines = [] + for move in srt_picking.move_lines: + if move.product_uom_qty > 0: + return_lines.append((0, 0, { + 'product_id': move.product_id.id, + 'quantity': move.product_uom_qty, + 'move_id': move.id, + })) + _logger.info( + f"🔁 BU/OUT baru dari SRT | {move.product_id.display_name} | qty={move.product_uom_qty}") + + bu_out_wizard = self.env['stock.return.picking'].with_context({ 'active_id': srt_picking.id, 'default_location_id': BU_OUTPUT_LOCATION_ID, 'default_location_dest_id': PARTNER_LOCATION_ID, 'from_ui': False, }).create({ 'picking_id': srt_picking.id, - 'location_id': PARTNER_LOCATION_ID, - 'original_location_id': BU_OUTPUT_LOCATION_ID - }).create_returns() - new_out = self.env['stock.picking'].browse(bu_out_new.get('res_id')) + 'location_id': BU_OUTPUT_LOCATION_ID, + 'original_location_id': PARTNER_LOCATION_ID, + 'product_return_moves': return_lines + }) + bu_out_vals = bu_out_wizard.create_returns() + new_out = self.env['stock.picking'].browse(bu_out_vals['res_id']) new_out.write({ 'location_id': BU_OUTPUT_LOCATION_ID, 'location_dest_id': PARTNER_LOCATION_ID, 'group_id': bu_out.group_id.id, 'tukar_guling_id': record.id, + 'sale_order': record.origin }) created_returns.append(new_out) + _logger.info(f"✅ BU/OUT Baru dari SRT created: {new_out.name}") - # Dari ORT → BU/PICK baru + # BU/PICK Baru dari ORT for ort_p in ort_pickings: - bu_pick_new = self.env['stock.return.picking'].with_context({ + return_lines = [] + for move in ort_p.move_lines: + if move.product_uom_qty > 0: + return_lines.append((0, 0, { + 'product_id': move.product_id.id, + 'quantity': move.product_uom_qty, + 'move_id': move.id + })) + _logger.info( + f"🔁 BU/PICK baru dari ORT {ort_p.name} | {move.product_id.display_name} | qty={move.product_uom_qty}") + + if not return_lines: + _logger.warning(f"❌ Tidak ada qty > 0 di ORT {ort_p.name}, dilewati.") + continue + + bu_pick_wizard = self.env['stock.return.picking'].with_context({ 'active_id': ort_p.id, - 'default_location_id': BU_OUTPUT_LOCATION_ID, - 'default_location_dest_id': BU_STOCK_LOCATION_ID, + 'default_location_id': BU_STOCK_LOCATION_ID, + 'default_location_dest_id': BU_OUTPUT_LOCATION_ID, 'from_ui': False, }).create({ 'picking_id': ort_p.id, 'location_id': BU_STOCK_LOCATION_ID, - 'original_location_id': BU_OUTPUT_LOCATION_ID - }).create_returns() - new_pick = self.env['stock.picking'].browse(bu_pick_new.get('res_id')) + 'original_location_id': BU_OUTPUT_LOCATION_ID, + 'product_return_moves': return_lines + }) + bu_pick_vals = bu_pick_wizard.create_returns() + new_pick = self.env['stock.picking'].browse(bu_pick_vals['res_id']) new_pick.write({ - 'location_id': BU_OUTPUT_LOCATION_ID, - 'location_dest_id': BU_STOCK_LOCATION_ID, + 'location_id': BU_STOCK_LOCATION_ID, + 'location_dest_id': BU_OUTPUT_LOCATION_ID, 'group_id': bu_out.group_id.id, 'tukar_guling_id': record.id, + 'sale_order': record.origin }) + new_pick.action_assign() # Penting agar bisa trigger check koli + new_pick.action_confirm() created_returns.append(new_pick) + _logger.info(f"✅ BU/PICK Baru dari ORT created: {new_pick.name}") if not created_returns: raise UserError("Tidak ada dokumen retur berhasil dibuat.") - _logger.info("✅ Created %s returns: %s", len(created_returns), ", ".join([p.name for p in created_returns])) + _logger.info("✅ Finished _create_pickings(). Created %s returns: %s", + len(created_returns), + ", ".join([p.name for p in created_returns])) class TukarGulingLine(models.Model): |
