summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-06-18 13:32:05 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-06-18 13:32:05 +0700
commitd1ff4bd35deac6c17a17e97f0904f67e113c5add (patch)
tree16cc13d381b45bd0174f1ee8dd393b60f89aa8f4
parentfe8c7bf1903242610d99381b5109506294648d10 (diff)
<miqdad> revisi, fetch item from bu out in tukar guling line
-rw-r--r--indoteknik_custom/models/tukar_guling.py141
-rw-r--r--indoteknik_custom/views/tukar_guling.xml14
-rw-r--r--indoteknik_custom/views/tukar_guling_po.xml4
3 files changed, 122 insertions, 37 deletions
diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py
index 7ed6e10f..a5724104 100644
--- a/indoteknik_custom/models/tukar_guling.py
+++ b/indoteknik_custom/models/tukar_guling.py
@@ -4,6 +4,7 @@ import logging
_logger = logging.getLogger(__name__)
+
class TukarGuling(models.Model):
_name = 'tukar.guling'
_description = 'Tukar Guling'
@@ -21,14 +22,13 @@ class TukarGuling(models.Model):
)
name = fields.Char('Number', required=True, copy=False, readonly=True, default='New')
date = fields.Datetime('Date', default=fields.Datetime.now, required=True)
- out_num = fields.Many2one('stock.picking', 'Nomor BU/Out',
- domain=[('picking_type_id.code', '=', 'outgoing')])
+ operations = fields.Many2one('stock.picking', 'Operations',
+ domain=[('picking_type_id.code', '=', 'outgoing')], help='Nomor BU/Out atau BU/Pick')
ba_num = fields.Text('Nomor BA')
notes = fields.Text('Notes')
return_type = fields.Selection(String='Return Type', selection=[
- ('tukar_guling', 'Tukar Guling'), # -> barang yang sama
- ('revisi_so', 'Revisi SO'), # -> ganti barang ?
- ('credit_memo', 'Credit Memo')]) # -> dijadiin credit memo
+ ('tukar_guling', 'Tukar Guling'), # -> barang yang sama
+ ('revisi_so', 'Revisi SO')])
state = fields.Selection(string='Status', selection=[
('draft', 'Draft'),
('approval_sales', ' Approval Sales'),
@@ -40,24 +40,108 @@ class TukarGuling(models.Model):
line_ids = fields.One2many('tukar.guling.line', 'tukar_guling_id', string='Product Lines')
- @api.constrains('return_type', 'out_num')
+ @api.onchange('operations')
+ def _onchange_operations(self):
+ """Auto-populate lines ketika operations dipilih"""
+ if self.operations:
+ # Clear existing lines
+ self.line_ids = [(5, 0, 0)]
+
+ # Set origin dari operations
+ if self.operations.origin:
+ self.origin = self.operations.origin
+
+ # Auto-populate lines dari move_ids operations
+ lines_data = []
+ sequence = 10
+
+ # 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
+
+ # Debug logging
+ _logger = logging.getLogger(__name__)
+ _logger.info(f"BU/OUT: {self.operations.name}, State: {self.operations.state}")
+ _logger.info(f"Total moves found: {len(moves_to_check)}")
+
+ 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
+
+ if lines_data:
+ self.line_ids = lines_data
+ _logger.info(f"Created {len(lines_data)} lines")
+ else:
+ _logger.info("No lines created - no valid moves found")
+ else:
+ # Clear lines jika operations dikosongkan
+ self.line_ids = [(5, 0, 0)]
+ self.origin = False
+
+ def action_populate_lines(self):
+ """Manual button untuk populate lines - sebagai alternatif"""
+ self.ensure_one()
+ if not self.operations:
+ raise UserError("Pilih BU/OUT terlebih dahulu!")
+
+ # Clear existing lines
+ self.line_ids = [(5, 0, 0)]
+
+ lines_data = []
+ sequence = 10
+
+ # Ambil semua stock moves dari operations
+ for move in self.operations.move_ids:
+ if 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
+
+ if lines_data:
+ self.line_ids = lines_data
+ else:
+ raise UserError("Tidak ditemukan barang di BU/OUT yang dipilih!")
+
+ @api.constrains('return_type', 'operations')
def _check_required_bu_fields(self):
for record in self:
- if record.return_type in ['revisi_so', 'credit_memo', 'tukar_guling'] and not record.out_num:
+ if record.return_type in ['revisi_so', 'tukar_guling'] and not record.operations:
raise ValidationError("BU/Out harus diisi!")
@api.constrains('line_ids', 'state')
def _check_product_lines(self):
"""Constraint: Product lines harus ada jika state bukan draft"""
for record in self:
- if record.state in ('approval_sales', 'approval_logistic', 'approval_finance', 'done') and not record.line_ids:
+ if record.state in ('approval_sales', 'approval_logistic', 'approval_finance',
+ 'done') and not record.line_ids:
raise ValidationError("Product lines harus diisi sebelum submit atau approve!")
def _validate_product_lines(self):
"""Helper method untuk validasi product lines"""
self.ensure_one()
-
# Check ada product lines
if not self.line_ids:
raise UserError("Belum ada product lines yang ditambahkan!")
@@ -78,9 +162,9 @@ class TukarGuling(models.Model):
def create(self, vals):
if not vals.get('name') or vals['name'] == 'New':
vals['name'] = self.env['ir.sequence'].next_by_code('tukar.guling') or 'New'
- # Auto-fill origin from out_num
- if not vals.get('origin') and vals.get('out_num'):
- picking = self.env['stock.picking'].browse(vals['out_num'])
+ # Auto-fill origin from operations
+ if not vals.get('origin') and vals.get('operations'):
+ picking = self.env['stock.picking'].browse(vals['operations'])
if picking.origin:
vals['origin'] = picking.origin
return super(TukarGuling, self).create(vals)
@@ -109,8 +193,8 @@ class TukarGuling(models.Model):
return new_record
def write(self, vals):
- if 'out_num' in vals and not vals.get('origin'):
- picking = self.env['stock.picking'].browse(vals['out_num'])
+ if 'operations' in vals and not vals.get('origin'):
+ picking = self.env['stock.picking'].browse(vals['operations'])
if picking.origin:
vals['origin'] = picking.origin
@@ -145,7 +229,7 @@ class TukarGuling(models.Model):
def action_approve(self):
self.ensure_one()
- if not self.out_num:
+ if not self.operations:
raise UserError("BU/Out harus diisi!")
if not self.return_type:
@@ -170,6 +254,7 @@ class TukarGuling(models.Model):
rec._create_pickings()
else:
raise UserError("Status ini tidak bisa di-approve.")
+
def action_cancel(self):
self.ensure_one()
# if self.state == 'done':
@@ -177,10 +262,10 @@ class TukarGuling(models.Model):
self.state = 'cancel'
def _create_pickings(self):
- if not self.out_num:
+ if not self.operations:
raise UserError("BU/Out harus diisi terlebih dahulu.")
- origin_so = self.out_num.origin
+ origin_so = self.operations.origin
if not origin_so:
raise UserError("BU/OUT tidak memiliki origin (SO), tidak bisa cari BU/PICK.")
@@ -206,15 +291,15 @@ class TukarGuling(models.Model):
# Lokasi
location_dest_id = srt_type.default_location_dest_id.id
location_dest_id_ort = ort_type.default_location_dest_id.id
- location_customer = self.out_num.location_dest_id
+ location_customer = self.operations.location_dest_id
- # 1. BU/SRT: retur dari out_num
+ # 1. BU/SRT: retur dari operations
srt_picking = Picking.create({
- 'partner_id': self.out_num.partner_id.id,
+ 'partner_id': self.operations.partner_id.id,
'picking_type_id': srt_type.id,
'location_id': location_customer.id,
'location_dest_id': location_dest_id,
- 'origin': f"Retur {self.out_num.name}",
+ 'origin': f"Retur {self.operations.name}",
'tukar_guling_id': self.id,
'group_id': group_id,
'move_ids_without_package': [
@@ -232,7 +317,7 @@ class TukarGuling(models.Model):
srt_picking.action_confirm()
# 2. Cari BU/PICK dari SO yang sama
- origin_so = self.out_num.origin
+ origin_so = self.operations.origin
if not origin_so:
raise UserError("BU/OUT tidak memiliki origin (SO), tidak bisa cari BU/PICK.")
@@ -246,7 +331,7 @@ class TukarGuling(models.Model):
# 3. BU/ORT: retur dari BU/PICK
ort_picking = Picking.create({
- 'partner_id': self.out_num.partner_id.id,
+ 'partner_id': self.operations.partner_id.id,
'picking_type_id': ort_type.id,
'location_id': location_dest_id,
'location_dest_id': location_dest_id_ort,
@@ -266,7 +351,7 @@ class TukarGuling(models.Model):
]
})
ort_picking.action_confirm()
-
+ ort_picking.action_assign()
class TukarGulingPO(models.Model):
_name = 'tukar.guling.po'
@@ -274,7 +359,7 @@ class TukarGulingPO(models.Model):
name = fields.Char('Number', required=True, copy=False, readonly=True, default='New')
date = fields.Datetime('Date', default=fields.Datetime.now, required=True)
- out_num = fields.Many2one('stock.picking', 'Nomor BU/Out',
+ operations = fields.Many2one('stock.picking', 'Nomor BU/Out',
domain=[('picking_type_id.code', '=', 'outgoing')])
ba_num = fields.Text('Nomor BA')
notes = fields.Text('Notes')
@@ -296,10 +381,10 @@ class TukarGulingPO(models.Model):
('debit_memo', 'Debit Memo'),
], string='Return Type', required=True)
- @api.constrains('return_type', 'out_num')
+ @api.constrains('return_type', 'operations')
def _check_required_bu_fields(self):
for record in self:
- if record.return_type in ['tukar_guling', 'revisi_po', 'debit_memo'] and not record.out_num:
+ if record.return_type in ['tukar_guling', 'revisi_po', 'debit_memo'] and not record.operations:
raise ValidationError("BU/Out harus diisi!")
@api.constrains('line_ids', 'state')
@@ -369,7 +454,7 @@ class TukarGulingPO(models.Model):
def action_approve(self):
self.ensure_one()
- if not self.out_num:
+ if not self.operations:
raise UserError("BU/Out harus diisi!")
if not self.return_type:
diff --git a/indoteknik_custom/views/tukar_guling.xml b/indoteknik_custom/views/tukar_guling.xml
index 9f8a6ff6..c775c301 100644
--- a/indoteknik_custom/views/tukar_guling.xml
+++ b/indoteknik_custom/views/tukar_guling.xml
@@ -3,7 +3,7 @@
<data>
<!-- Action -->
<record id="action_pengajuan_tukar_guling" model="ir.actions.act_window">
- <field name="name">Pengajuan Tukar Guling SO</field>
+ <field name="name">Pengajuan Return SO</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">tukar.guling</field>
<field name="view_mode">tree,form</field>
@@ -11,14 +11,14 @@
<!-- Menu -->
<menuitem
id="menu_pengajuan_tukar_guling"
- name="Pengajuan Tukar Guling SO"
+ name="Pengajuan Return SO"
parent="sale.sale_order_menu"
sequence="3"
action="action_pengajuan_tukar_guling"
/>
<!-- Sequence -->
<record id="seq_tukar_guling" model="ir.sequence">
- <field name="name">Pengajuan Tukar Guling SO</field>
+ <field name="name">Pengajuan Return SO</field>
<field name="code">tukar.guling</field>
<field name="prefix">PTG/</field>
<field name="padding">5</field>
@@ -34,7 +34,7 @@
<tree create="1" delete="1" default_order="create_date desc">
<field name="name"/>
<field name="date"/>
- <field name="out_num" string="BU/Out"/>
+ <field name="operations" string="Operations"/>
<field name="ba_num" string="Nomor BA"/>
<field name="return_type" string="Return Type"/>
<field name="state" widget="badge"
@@ -91,10 +91,10 @@
<field name="return_type"/>
<!-- <field name="ort_num" readonly="1"/>-->
<!-- <field name="srt_num" readonly="1"/>-->
- <field name="out_num" string="BU/Out"
+ <field name="operations" string="Operations"
attrs="{
- 'invisible': [('return_type', 'not in', ['revisi_so', 'credit_memo', 'tukar_guling'])],
- 'required': [('return_type', 'in', ['revisi_so', 'credit_memo'])]
+ 'invisible': [('return_type', 'not in', ['revisi_so','tukar_guling'])],
+ 'required': [('return_type', 'in', ['revisi_so'])]
}"/>
<field name="origin" readonly="1"/>
</group>
diff --git a/indoteknik_custom/views/tukar_guling_po.xml b/indoteknik_custom/views/tukar_guling_po.xml
index 3ad269ee..76d85904 100644
--- a/indoteknik_custom/views/tukar_guling_po.xml
+++ b/indoteknik_custom/views/tukar_guling_po.xml
@@ -36,7 +36,7 @@
<tree create="1" delete="1" default_order="create_date desc">
<field name="name"/>
<field name="date"/>
- <field name="out_num" string="BU/Out"/>
+ <field name="operations" string="BU/Out"/>
<field name="ba_num" string="Nomor BA"/>
<field name="return_type" string="Return Type"/>
<field name="state" widget="badge"
@@ -83,7 +83,7 @@
<group>
<field name="date" string="Date" readonly="1"/>
<field name="return_type"/>
- <field name="out_num" string="BU/Out"
+ <field name="operations" string="BU/Out"
attrs="{
'invisible': [('return_type', 'not in', ['revisi_po', 'debit_memo', 'tukar_guling'])],
'required': [('return_type', 'in', ['revisi_po', 'debit_memo'])]