summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-07-16 19:26:31 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-07-16 19:26:31 +0700
commit6a763b8aa16bc71b345378a9155c386b4d7bd400 (patch)
tree2b43f3498b1e2ed72781163e557edb078cbdde9a
parent2221c9ffcdce7bf5f142e3e65fa058b4dc07de8f (diff)
parentefa1650aae2bc2dca99624092adcc21f87dab648 (diff)
Merge branch 'tukar_guling' of https://bitbucket.org/altafixco/indoteknik-addons into tukar_guling
merge
-rw-r--r--indoteknik_custom/models/stock_picking.py2
-rw-r--r--indoteknik_custom/models/stock_picking_return.py21
-rw-r--r--indoteknik_custom/models/tukar_guling.py205
-rw-r--r--indoteknik_custom/models/tukar_guling_po.py44
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv3
-rw-r--r--indoteknik_custom/views/tukar_guling.xml156
6 files changed, 273 insertions, 158 deletions
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index 868a96c1..3e152f10 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -2523,6 +2523,8 @@ class KonfirmKoli(models.Model):
copy=False,
)
pick_id = fields.Many2one('stock.picking', string='Pick')
+ product_id = fields.Many2one('product.product', string='Product')
+ qty_done = fields.Float(string='Qty Done')
@api.constrains('pick_id')
def _check_duplicate_pick_id(self):
diff --git a/indoteknik_custom/models/stock_picking_return.py b/indoteknik_custom/models/stock_picking_return.py
index a9781d3c..e274a147 100644
--- a/indoteknik_custom/models/stock_picking_return.py
+++ b/indoteknik_custom/models/stock_picking_return.py
@@ -89,6 +89,27 @@ class StockReturnPicking(models.TransientModel):
if line_vals:
context['default_line_ids'] = line_vals
+ if picking.picking_type_id.id == 29:
+ mapping_koli_vals = []
+ sequence = 10
+ returned_product_ids = set()
+
+ # Ambil move lines dari BU/PICK
+ for move_line in picking.move_line_ids_without_package:
+ # Cek apakah produk ini ada di daftar retur dan qty_done > 0
+ if move_line.product_id.id in returned_product_ids and move_line.qty_done > 0:
+ mapping_koli_vals.append((0, 0, {
+ 'sequence': sequence,
+ 'pick_id': picking.id, # ID BU/PICK itu sendiri
+ 'product_id': move_line.product_id.id,
+ 'qty_done': move_line.qty_done,
+ 'qty_return': move_line.qty_done,
+ }))
+ sequence += 10
+
+ if mapping_koli_vals:
+ context['default_mapping_koli_ids'] = mapping_koli_vals
+
if picking.purchase_id or 'PO' in picking.origin:
_logger.info("Redirect ke Tukar Guling PO via purchase_id / origin")
return {
diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py
index 7e857d02..2c39b547 100644
--- a/indoteknik_custom/models/tukar_guling.py
+++ b/indoteknik_custom/models/tukar_guling.py
@@ -55,6 +55,25 @@ class TukarGuling(models.Model):
], default='draft', tracking=True, required=True)
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')
+
+ 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
+ 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)
+
+ 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 mapping koli sesuai dengan product lines")
@api.onchange('operations')
def _onchange_operations(self):
@@ -71,10 +90,33 @@ class TukarGuling(models.Model):
# Hanya update origin, jangan ubah lines
if self.operations.origin:
self.origin = self.operations.origin
- return
+ _logger.info("📌 Menggunakan product lines dari return wizard, tidak populate ulang.")
+
+ # 🚀 Tapi tetap populate mapping koli jika BU/OUT
+ if self.operations.picking_type_id.id == 29:
+ mapping_koli_data = []
+ sequence = 10
+ tg_product_ids = self.line_ids.mapped('product_id.id')
+
+ for koli_line in self.operations.konfirm_koli_lines:
+ pick_move = koli_line.pick_id.move_line_ids_without_package
+ if pick_move.product_id.id in tg_product_ids:
+ mapping_koli_data.append((0, 0, {
+ 'sequence': sequence,
+ 'pick_id': koli_line.pick_id.id,
+ 'product_id': pick_move.product_id.id,
+ 'qty_done': pick_move.qty_done,
+ 'qty_return': 0
+ }))
+ sequence += 10
+
+ self.mapping_koli_ids = mapping_koli_data
+ _logger.info(f"✅ Created {len(mapping_koli_data)} mapping koli lines (from return wizard)")
+ return # keluar supaya tidak populate ulang lines
# Clear existing lines hanya jika tidak dari return picking
self.line_ids = [(5, 0, 0)]
+ self.mapping_koli_ids = [(5, 0, 0)] # Clear existing mapping koli juga
# Set origin dari operations
if self.operations.origin:
@@ -87,40 +129,70 @@ class TukarGuling(models.Model):
# Untuk Odoo 14, gunakan move_ids_without_package atau move_lines
moves_to_check = []
- # 1. move_ids_without_package (standard di Odoo 14)
if hasattr(self.operations, 'move_ids_without_package') and self.operations.move_ids_without_package:
moves_to_check = self.operations.move_ids_without_package
- # 2. move_lines (backup untuk versi lama)
elif hasattr(self.operations, 'move_lines') and self.operations.move_lines:
moves_to_check = self.operations.move_lines
+ # Collect product data
+ product_data = {}
for move in moves_to_check:
- _logger.info(
- f"Move: {move.name}, Product: {move.product_id.name if move.product_id else 'No Product'}, Qty: {move.product_uom_qty}, State: {move.state}")
-
- # Ambil semua move yang ada quantity
if move.product_id and move.product_uom_qty > 0:
- lines_data.append((0, 0, {
- 'sequence': sequence,
- 'product_id': move.product_id.id,
- 'product_uom_qty': move.product_uom_qty,
- 'product_uom': move.product_uom.id,
- 'name': move.name or move.product_id.display_name,
- }))
- sequence += 10
+ product_id = move.product_id.id
+ if product_id not in product_data:
+ product_data[product_id] = {
+ 'product': move.product_id,
+ 'qty': move.product_uom_qty,
+ 'uom': move.product_uom.id,
+ 'name': move.name or move.product_id.display_name
+ }
+
+ # Buat lines_data
+ for product_id, data in product_data.items():
+ lines_data.append((0, 0, {
+ 'sequence': sequence,
+ 'product_id': product_id,
+ 'product_uom_qty': data['qty'],
+ 'product_uom': data['uom'],
+ 'name': data['name'],
+ }))
+ sequence += 10
if lines_data:
self.line_ids = lines_data
- _logger.info(f"Created {len(lines_data)} lines")
+ _logger.info(f"Created {len(lines_data)} product lines")
+
+ # Prepare mapping koli jika BU/OUT
+ mapping_koli_data = []
+ sequence = 10
+
+ if self.operations.picking_type_id.id == 29:
+ tg_product_ids = [p for p in product_data]
+ for koli_line in self.operations.konfirm_koli_lines:
+ pick_move = koli_line.pick_id.move_line_ids_without_package
+ if pick_move.product_id.id in tg_product_ids:
+ mapping_koli_data.append((0, 0, {
+ 'sequence': sequence,
+ 'pick_id': koli_line.pick_id.id,
+ 'product_id': pick_move.product_id.id,
+ 'qty_done': pick_move.qty_done
+ }))
+ sequence += 10
+
+ if mapping_koli_data:
+ self.mapping_koli_ids = mapping_koli_data
+ _logger.info(f"Created {len(mapping_koli_data)} mapping koli lines")
+ else:
+ _logger.info("No mapping koli lines created")
else:
- _logger.info("No lines created - no valid moves found")
+ _logger.info("No product lines created - no valid moves found")
else:
- # Clear lines jika operations dikosongkan, kecuali dari return picking
from_return_picking = self.env.context.get('from_return_picking', False) or \
self.env.context.get('default_line_ids', False)
if not from_return_picking:
self.line_ids = [(5, 0, 0)]
+ self.mapping_koli_ids = [(5, 0, 0)]
self.origin = False
@@ -409,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:
@@ -469,59 +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 = []
- # 🔥 Hanya pakai qty dari tukar guling line
- 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)
@@ -529,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'
@@ -568,3 +649,15 @@ class StockPicking(models.Model):
_inherit = 'stock.picking'
tukar_guling_id = fields.Many2one('tukar.guling', string='Tukar Guling Ref')
+
+
+class TukarGulingMappingKoli(models.Model):
+ _name = 'tukar.guling.mapping.koli'
+ _description = 'Mapping Koli di Tukar Guling'
+
+ tukar_guling_id = fields.Many2one('tukar.guling', string='Tukar Guling')
+ 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 diretur')
+ sequence = fields.Integer(string='Sequence', default=10) \ No newline at end of file
diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py
index 6d7d7335..88c4722a 100644
--- a/indoteknik_custom/models/tukar_guling_po.py
+++ b/indoteknik_custom/models/tukar_guling_po.py
@@ -311,7 +311,7 @@ class TukarGulingPO(models.Model):
self._validate_product_lines()
self._check_not_allow_tukar_guling_on_bu_input()
- if self.operations and self.operations.picking_type_id.id == 28 and self.return_type == 'tukar_guling':
+ if self.operations.picking_type_id.id == 28:
group = self.operations.group_id
if group:
# Cari BU/PUT dalam group yang sama
@@ -325,11 +325,12 @@ class TukarGulingPO(models.Model):
raise UserError("❌ Tidak bisa retur BU/INPUT karena BU/PUT sudah Done!")
picking = self.operations
- if picking.picking_type_id.id == 75:
+ pick_id = self.operations.picking_type_id.id
+ if pick_id == 75:
if picking.state != 'done':
raise UserError("BU/PUT belum Done!")
- if picking.picking_type_id.id != 75 or picking.picking_type_id.id != 28:
+ if pick_id not in [75, 28]:
raise UserError("❌ Tidak bisa retur bukan BU/INPUT atau BU/PUT!")
if self._is_already_returned(self.operations):
@@ -388,7 +389,7 @@ class TukarGulingPO(models.Model):
if not record.operations:
raise UserError("BU Operations belum dipilih.")
- created_returns = []
+ created_returns = self.env['stock.picking']
group = record.operations.group_id
bu_inputs = bu_puts = self.env['stock.picking']
@@ -403,17 +404,17 @@ class TukarGulingPO(models.Model):
else:
raise UserError("Group ID tidak ditemukan pada BU Operations.")
- PARTNER_LOCATION_ID = 4
- BU_INPUT_LOCATION_ID = 58
- BU_STOCK_LOCATION_ID = 57
-
def _create_return_from_picking(picking):
if not picking:
- return None
+ return self.env['stock.picking']
grup = record.operations.group_id
- # Mapping lokasi sesuai picking type
+ # Tentukan location
+ PARTNER_LOCATION_ID = 4
+ BU_INPUT_LOCATION_ID = 58
+ BU_STOCK_LOCATION_ID = 57
+
if picking.picking_type_id.id == 28:
default_location_id = BU_INPUT_LOCATION_ID
default_location_dest_id = PARTNER_LOCATION_ID
@@ -427,7 +428,7 @@ class TukarGulingPO(models.Model):
default_location_id = PARTNER_LOCATION_ID
default_location_dest_id = BU_INPUT_LOCATION_ID
else:
- return None
+ return self.env['stock.picking']
return_context = dict(self.env.context)
return_context.update({
@@ -443,7 +444,6 @@ class TukarGulingPO(models.Model):
'original_location_id': default_location_id
})
- # Sesuai line tukar guling
return_lines = []
for line in record.line_ids:
move = picking.move_lines.filtered(lambda m: m.product_id == line.product_id)
@@ -455,20 +455,17 @@ class TukarGulingPO(models.Model):
}))
else:
raise UserError(
- _("Tidak ditemukan move line di picking %s untuk produk %s")
- % (picking.name, line.product_id.display_name)
+ _("Tidak ditemukan move line di picking %s untuk produk %s") %
+ (picking.name, line.product_id.display_name)
)
if not return_lines:
- return None
+ 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_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_id': default_location_id,
'location_dest_id': default_location_dest_id,
@@ -476,7 +473,6 @@ class TukarGulingPO(models.Model):
'tukar_guling_po_id': record.id,
})
- # Paksa lokasi di move lines juga
for move in return_picking.move_lines:
move.write({
'location_id': default_location_id,
@@ -490,31 +486,31 @@ class TukarGulingPO(models.Model):
# Kalau dari BU INPUT → hanya PRT
prt = _create_return_from_picking(record.operations)
if prt:
- created_returns.append(prt)
+ created_returns |= prt
else:
# 1. Dari BU PUT buat VRT
for bu_put in bu_puts:
vrt = _create_return_from_picking(bu_put)
if vrt:
- created_returns.append(vrt)
+ created_returns |= vrt
# 2. Dari BU INPUT buat PRT
for bu_input in bu_inputs:
prt = _create_return_from_picking(bu_input)
if prt:
- created_returns.append(prt)
+ created_returns |= prt
# 3. Kalau tukar guling buat lanjut INPUT & PUT
if record.return_type == 'tukar_guling':
for prt in created_returns.filtered(lambda p: p.picking_type_id.id == 76):
bu_input = _create_return_from_picking(prt)
if bu_input:
- created_returns.append(bu_input)
+ created_returns |= bu_input
for vrt in created_returns.filtered(lambda p: p.picking_type_id.id == 77):
bu_put = _create_return_from_picking(vrt)
if bu_put:
- created_returns.append(bu_put)
+ created_returns |= bu_put
if not created_returns:
raise UserError("Tidak ada dokumen retur yang berhasil dibuat.")
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index 85781524..eb646dfb 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -187,4 +187,5 @@ access_approval_payment_term,access.approval.payment.term,model_approval_payment
access_tukar_guling_all_users,tukar.guling.all.users,model_tukar_guling,base.group_user,1,1,1,1
access_tukar_guling_line_all_users,tukar.guling.line.all.users,model_tukar_guling_line,base.group_user,1,1,1,1
access_tukar_guling_po_all_users,tukar.guling.po.all.users,model_tukar_guling_po,base.group_user,1,1,1,1
-access_tukar_guling_line_po_all_users,tukar.guling.line.po.all.users,model_tukar_guling_line_po,base.group_user,1,1,1,1 \ No newline at end of file
+access_tukar_guling_line_po_all_users,tukar.guling.line.po.all.users,model_tukar_guling_line_po,base.group_user,1,1,1,1
+access_tukar_guling_mapping_koli_all_users,tukar.guling.mapping.koli.all.users,model_tukar_guling_mapping_koli,base.group_user,1,1,1,1 \ No newline at end of file
diff --git a/indoteknik_custom/views/tukar_guling.xml b/indoteknik_custom/views/tukar_guling.xml
index 41e9a18d..acc48d3f 100644
--- a/indoteknik_custom/views/tukar_guling.xml
+++ b/indoteknik_custom/views/tukar_guling.xml
@@ -36,81 +36,83 @@
</field>
</record>
<!-- Form View -->
- <record id="pengajuan_tukar_guling_form" model="ir.ui.view">
- <field name="name">pengajuan.tukar.guling.form</field>
- <field name="model">tukar.guling</field>
- <field name="arch" type="xml">
- <form>
- <header>
- <button name="action_submit" string="Submit" type="object"
- class="btn-primary"
- attrs="{'invisible': [('state', '!=', 'draft')]}"/>
- <button name="action_approve" string="Approve" type="object"
- class="btn-primary"
- attrs="{'invisible': [('state', 'not in', ['approval_sales', 'approval_logistic', 'approval_finance'])]}"/>
- <button name="action_cancel" string="Cancel" type="object"
- class="btn-secondary"
- attrs="{'invisible': [('state', '=', 'cancel')]}"
- confirm="Are you sure you want to cancel this record?"/>
- <button name="action_draft" string="Set to Draft" type="object"
- class="btn-secondary"
- attrs="{'invisible': [('state', '!=', 'cancel')]}"
- confirm="Are you sure you want to reset this record to draft?"/>
- <field name="state" widget="statusbar" readonly="1"
- statusbar_visible="draft,approval_sales,approval_logistic,approval_finance,done"/>
- </header>
- <sheet>
- <div class="oe_button_box">
- <button name="action_view_picking"
- type="object"
- class="oe_stat_button"
- icon="fa-truck"
- attrs="{'invisible': [('picking_ids', '=', False), ('state', 'in', ['draft', 'approval_sales', 'approval_logistic', 'approval_finance'])]}">
- <field name="picking_ids" widget="statinfo" string="Delivery"/>
- </button>
- </div>
- <div class="oe_title">
- <h1>
- <field name="name" readonly="1" class="oe_inline"/>
- </h1>
- </div>
- <group>
- <group>
- <field name="date" string="Date" readonly="1"/>
- <field name="return_type"/>
- <!-- <field name="ort_num" readonly="1"/>-->
- <!-- <field name="srt_num" readonly="1"/>-->
- <field name="operations" string="Operations"
- attrs="{
- 'required': [('return_type', 'in', ['revisi_so', 'tukar_guling'])]
- }"/>
- <field name="origin" readonly="1"/>
- <!-- <field name="origin_so" readonly="1"/>-->
- </group>
- <group>
- <field name="ba_num" string="Nomor BA"/>
- <field name="notes"/>
- </group>
- </group>
- <!-- Product Lines -->
- <notebook>
- <page string="Product Lines" name="product_lines" create="0" edit="0">
- <field name="line_ids" delete="1" readonly="1">
- <tree string="Product Lines">
- <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_uom_qty" string="Quantity"/>
- <field name="product_uom" string="UoM"
- options="{'no_create': True, 'no_create_edit': True}"/>
- </tree>
- </field>
- </page>
- </notebook>
- </sheet>
- </form>
- </field>
- </record>
- </data>
+ <record id="pengajuan_tukar_guling_form" model="ir.ui.view">
+ <field name="name">pengajuan.tukar.guling.form</field>
+ <field name="model">tukar.guling</field>
+ <field name="arch" type="xml">
+ <form>
+ <header>
+ <button name="action_submit" string="Submit" type="object"
+ class="btn-primary"
+ attrs="{'invisible': [('state', '!=', 'draft')]}"/>
+ <button name="action_approve" string="Approve" type="object"
+ class="btn-primary"
+ attrs="{'invisible': [('state', 'not in', ['approval_sales', 'approval_logistic', 'approval_finance'])]}"/>
+ <button name="action_cancel" string="Cancel" type="object"
+ class="btn-secondary"
+ attrs="{'invisible': [('state', '=', 'cancel')]}"/>
+ <button name="action_draft" string="Set to Draft" type="object"
+ class="btn-secondary"
+ attrs="{'invisible': [('state', '!=', 'cancel')]}"/>
+ <field name="state" widget="statusbar" readonly="1"
+ statusbar_visible="draft,approval_sales,approval_logistic,approval_finance,done"/>
+ </header>
+ <sheet>
+ <div class="oe_button_box">
+ <button name="action_view_picking"
+ type="object"
+ class="oe_stat_button"
+ icon="fa-truck"
+ attrs="{'invisible': [('picking_ids', '=', False), ('state', 'in', ['draft', 'approval_sales', 'approval_logistic', 'approval_finance'])]}">
+ <field name="picking_ids" widget="statinfo" string="Delivery"/>
+ </button>
+ </div>
+ <div class="oe_title">
+ <h1>
+ <field name="name" readonly="1" class="oe_inline"/>
+ </h1>
+ </div>
+ <group>
+ <group>
+ <field name="date" string="Date" readonly="1"/>
+ <field name="return_type"/>
+ <field name="operations"
+ attrs="{'required': [('return_type', 'in', ['revisi_so', 'tukar_guling'])]}"/>
+ <field name="origin" readonly="1"/>
+ </group>
+ <group>
+ <field name="ba_num" string="Nomor BA"/>
+ <field name="notes"/>
+ </group>
+ </group>
+ <notebook>
+ <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="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}"/>
+ </tree>
+ </field>
+ </page>
+ <page string="Mapping Koli" name="mapping_koli">
+ <field name="mapping_koli_ids">
+ <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>
+ </notebook>
+ </sheet>
+ </form>
+ </field>
+ </record>
+ </data>
</odoo> \ No newline at end of file