summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-07-16 17:40:22 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-07-16 17:40:22 +0700
commitefa1650aae2bc2dca99624092adcc21f87dab648 (patch)
treee9672a3cb9f724ef869bda24c4d58bac60f718b8
parent0e330178d087b2b4cb519c4e078f0fe25a76dfe5 (diff)
<miqdad> retur blm sesuai
-rw-r--r--indoteknik_custom/models/tukar_guling.py99
-rw-r--r--indoteknik_custom/views/tukar_guling.xml21
2 files changed, 65 insertions, 55 deletions
diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py
index a2168f5b..2c39b547 100644
--- a/indoteknik_custom/models/tukar_guling.py
+++ b/indoteknik_custom/models/tukar_guling.py
@@ -57,25 +57,23 @@ class TukarGuling(models.Model):
line_ids = fields.One2many('tukar.guling.line', 'tukar_guling_id', string='Product Lines')
mapping_koli_ids = fields.One2many('tukar.guling.mapping.koli', 'tukar_guling_id', string='Mapping Koli')
- @api.constrains('mapping_koli_ids')
def _check_mapping_koli(self):
for record in self:
if record.operations.picking_type_id.id == 29: # Only for BU/OUT
if not record.mapping_koli_ids:
raise UserError("❌ Mapping Koli belum diisi")
- # Calculate totals as integers
- total_mapping_qty = sum(int(mapping.qty_done) for mapping in record.mapping_koli_ids.qty_return)
+ # Calculate totals
+ total_mapping_qty = sum(int(mapping.qty_return) for mapping in record.mapping_koli_ids)
total_line_qty = sum(int(line.product_uom_qty) for line in record.line_ids)
- # Strict integer comparison
if total_mapping_qty != total_line_qty:
raise UserError(
"❌ Total quantity return di mapping koli (%d) tidak sama dengan quantity retur product lines (%d)" %
(total_mapping_qty, total_line_qty)
)
else:
- _logger.info("qty koli sesuai")
+ _logger.info("✅ Qty mapping koli sesuai dengan product lines")
@api.onchange('operations')
def _onchange_operations(self):
@@ -107,7 +105,8 @@ class TukarGuling(models.Model):
'sequence': sequence,
'pick_id': koli_line.pick_id.id,
'product_id': pick_move.product_id.id,
- 'qty_done': pick_move.qty_done
+ 'qty_done': pick_move.qty_done,
+ 'qty_return': 0
}))
sequence += 10
@@ -482,47 +481,39 @@ class TukarGuling(models.Model):
if not record.operations:
raise UserError("BU/OUT dari field operations tidak ditemukan.")
+ created_returns = []
+
bu_pick_to_return = record.operations.konfirm_koli_lines.pick_id
bu_out_to_return = record.operations
if not bu_pick_to_return and not bu_out_to_return:
raise UserError("Tidak ada BU/PICK atau BU/OUT yang selesai untuk diretur.")
- created_returns = []
-
- # Picking types & locations
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)
- def _create_return_from_picking(picking):
+ PARTNER_LOCATION_ID = 5
+ BU_OUTPUT_LOCATION_ID = 60
+ BU_STOCK_LOCATION_ID = 57
+
+ def _create_return_from_picking_grouped(picking):
if not picking:
return None
- grup = record.operations.group_id
- PARTNER_LOCATION_ID = 5
- BU_OUTPUT_LOCATION_ID = 60
- BU_STOCK_LOCATION_ID = 57
+ grup = record.operations.group_id
if picking.picking_type_id.id == 30:
- # BU/PICK → ORT
- return_type = ort_type
default_location_id = BU_OUTPUT_LOCATION_ID
default_location_dest_id = BU_STOCK_LOCATION_ID
elif picking.picking_type_id.id == 74:
- # ORT → BU/PICK
- return_type = bu_pick_type
default_location_id = BU_STOCK_LOCATION_ID
default_location_dest_id = BU_OUTPUT_LOCATION_ID
elif picking.picking_type_id.id == 29:
- # BU/OUT → SRT
- return_type = srt_type
default_location_id = PARTNER_LOCATION_ID
default_location_dest_id = BU_OUTPUT_LOCATION_ID
elif picking.picking_type_id.id == 73:
- # SRT → BU/OUT
- return_type = bu_out_type
default_location_id = BU_OUTPUT_LOCATION_ID
default_location_dest_id = PARTNER_LOCATION_ID
else:
@@ -542,58 +533,75 @@ class TukarGuling(models.Model):
'original_location_id': default_location_id
})
+ # 🔥 If BU/OUT, ambil qty dari mapping koli (group by product)
return_lines = []
- for line in record.line_ids:
- move = picking.move_lines.filtered(lambda m: m.product_id == line.product_id)
- if move:
+ if picking.picking_type_id.id == 29 and record.mapping_koli_ids:
+ grouped_qty = {}
+ for map_line in record.mapping_koli_ids:
+ pid = map_line.product_id.id
+ grouped_qty[pid] = grouped_qty.get(pid, 0) + map_line.qty_return
+
+ for pid, qty in grouped_qty.items():
+ move = picking.move_lines.filtered(lambda mv: mv.product_id.id == pid)
+ if move:
+ return_lines.append((0, 0, {
+ 'product_id': pid,
+ 'quantity': qty,
+ 'move_id': move[0].id,
+ }))
+ else:
+ raise UserError(_("Tidak ditemukan move line di picking %s untuk produk %s")
+ % (picking.name, map_line.product_id.display_name))
+ else:
+ # Default kalau bukan BU/OUT (misalnya ORT), retur full qty done
+ for move in picking.move_lines:
return_lines.append((0, 0, {
- 'product_id': line.product_id.id,
- 'quantity': line.product_uom_qty,
- 'move_id': move[0].id,
+ 'product_id': move.product_id.id,
+ 'quantity': move.quantity_done or move.product_uom_qty,
+ 'move_id': move.id,
}))
- else:
- raise UserError(
- _("Tidak ditemukan move line di picking %s untuk produk %s")
- % (picking.name, line.product_id.display_name)
- )
if not return_lines:
raise UserError(_("Tidak ada product line valid untuk retur picking %s") % picking.name)
return_wizard.product_return_moves = return_lines
return_vals = return_wizard.create_returns()
- return_id = return_vals.get('res_id')
- return_picking = self.env['stock.picking'].browse(return_id)
+ return_picking = self.env['stock.picking'].browse(return_vals.get('res_id'))
if not return_picking:
raise UserError("Retur gagal dibuat. Hasil create_returns: %s" % str(return_vals))
return_picking.write({
- 'location_dest_id': default_location_dest_id,
'location_id': default_location_id,
+ 'location_dest_id': default_location_dest_id,
'group_id': grup.id,
'tukar_guling_id': record.id,
})
+ for move in return_picking.move_lines:
+ move.write({
+ 'location_id': default_location_id,
+ 'location_dest_id': default_location_dest_id,
+ })
+
return return_picking
- # === PERBAIKI URUTAN ===
- srt = _create_return_from_picking(bu_out_to_return)
+ # === FLOW ===
+ srt = _create_return_from_picking_grouped(bu_out_to_return)
if srt:
created_returns.append(srt)
- picks = record.operations.konfirm_koli_lines.pick_id
- for picking in picks:
- ort = _create_return_from_picking(picking)
+ for picking in bu_pick_to_return:
+ ort = _create_return_from_picking_grouped(picking)
if ort:
created_returns.append(ort)
if record.return_type == 'tukar_guling':
- bu_pick = _create_return_from_picking(ort)
+ bu_pick = _create_return_from_picking_grouped(ort)
if bu_pick:
created_returns.append(bu_pick)
if record.return_type == 'tukar_guling' and srt:
- bu_out = _create_return_from_picking(srt)
+ bu_out = _create_return_from_picking_grouped(srt)
if bu_out:
created_returns.append(bu_out)
@@ -601,6 +609,7 @@ class TukarGuling(models.Model):
raise UserError("Tidak ada dokumen retur yang berhasil dibuat.")
+
class TukarGulingLine(models.Model):
_name = 'tukar.guling.line'
_description = 'Tukar Guling Line'
@@ -650,5 +659,5 @@ class TukarGulingMappingKoli(models.Model):
pick_id = fields.Many2one('stock.picking', string='BU PICK')
product_id = fields.Many2one('product.product', string='Product')
qty_done = fields.Float(string='Qty Done BU PICK')
- qty_return = fields.Float(string='Qty yang mau diretur')
- sequence = fields.Integer(string='Sequence', default=10)
+ qty_return = fields.Float(string='Qty diretur')
+ sequence = fields.Integer(string='Sequence', default=10) \ No newline at end of file
diff --git a/indoteknik_custom/views/tukar_guling.xml b/indoteknik_custom/views/tukar_guling.xml
index c36089ad..acc48d3f 100644
--- a/indoteknik_custom/views/tukar_guling.xml
+++ b/indoteknik_custom/views/tukar_guling.xml
@@ -86,13 +86,13 @@
</group>
</group>
<notebook>
- <page string="Product Lines" name="product_lines" create="0" edit="0">
- <field name="line_ids" delete="1" readonly="1">
- <tree string="Product Lines">
+ <page string="Product Lines" name="product_lines">
+ <field name="line_ids">
+ <tree string="Product Lines" editable="top" create="0" delete="1">
<field name="sequence" widget="handle"/>
- <field name="product_id" required="1"
- options="{'no_create': True, 'no_create_edit': True}"/>
- <field name="name" force_save="1"/>
+ <field name="product_id" required="0"
+ options="{'no_create': True, 'no_create_edit': True}" readonly="0"/>
+ <field name="name" force_save="0" readonly="1"/>
<field name="product_uom_qty" string="Quantity"/>
<field name="product_uom" string="UoM"
options="{'no_create': True, 'no_create_edit': True}"/>
@@ -101,10 +101,11 @@
</page>
<page string="Mapping Koli" name="mapping_koli">
<field name="mapping_koli_ids">
- <tree>
- <field name="pick_id"/>
- <field name="product_id"/>
- <field name="qty_done"/>
+ <tree editable="top" create="0" delete="1">
+ <field name="pick_id" readonly="1" force_save="1"/>
+ <field name="product_id" readonly="1" force_save="1"/>
+ <field name="qty_done" force_save="1"/>
+ <field name="qty_return"/>
</tree>
</field>
</page>