From 9c663e33bebc09d65614c5158c98270e964c9a06 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 30 Oct 2025 11:15:47 +0700 Subject: fix bug --- indoteknik_custom/models/sale_order.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 494aeaa2..b8de1697 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2716,11 +2716,13 @@ class SaleOrder(models.Model): if user.is_leader or user.is_sales_manager: return True - if user.id in (3401, 20, 3988, 17340): # admin (fida, nabila, ninda) + if not self.env.context.get("ask_approval") and user.id in (3401, 20, 3988, 17340): # admin (fida, nabila, ninda) raise UserError("Yahaha gabisa confirm so, minta ke sales nya ajah") - + if self.env.context.get("ask_approval") and user.id in (3401, 20, 3988): return True + + salesperson_id = self.user_id.id approver_id = user.id -- cgit v1.2.3 From 21738b9d99acac49a041ab0c2a7dd99c94e3ed12 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 30 Oct 2025 15:43:06 +0700 Subject: fix gk bisa edit tanggal kirim sj --- indoteknik_custom/models/stock_move.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 8f8ba66f..43c4676e 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -219,12 +219,14 @@ class StockMoveLine(models.Model): if done_qty == 0: line.delivery_status = 'none' elif done_qty > 0: - has_other_out = self.env['stock.picking'].search_count([ - ('group_id', '=', picking.group_id.id), - ('name', 'ilike', 'BU/OUT'), - ('id', '!=', picking.id), - ('state', '=', 'done'), - ]) + has_other_out = 0 + if picking.group_id and isinstance(picking.id, int): + has_other_out = self.env['stock.picking'].search_count([ + ('group_id', '=', picking.group_id.id), + ('name', 'ilike', 'BU/OUT'), + ('id', '!=', picking.id), + ('state', '=', 'done'), + ]) if has_other_out and done_qty == total_qty: line.delivery_status = 'partial_final' elif not has_other_out and done_qty >= total_qty: @@ -236,7 +238,6 @@ class StockMoveLine(models.Model): else: line.delivery_status = 'none' - # Ambil uom dari stock move @api.model def create(self, vals): -- cgit v1.2.3 From 2a5062c7e292086df579420545f79801b80967e2 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 30 Oct 2025 15:56:55 +0700 Subject: (andri) fix partner jurnal --- indoteknik_custom/models/advance_payment_request.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index 5a465ca4..66f0aac6 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -1194,7 +1194,8 @@ class AdvancePaymentSettlement(models.Model): if not self.pum_id or not self.pum_id.move_id: raise UserError("PUM terkait atau CAB belum tersedia.") - partner_id = self.pum_id.user_id.partner_id.id + # partner_id = self.pum_id.user_id.partner_id.id + partner_id = self.pum_id.applicant_name.partner_id.id cab_move = self.pum_id.move_id # Account Bank Intransit dari CAB: @@ -1424,7 +1425,8 @@ class AdvancePaymentCreateBill(models.TransientModel): # raise UserError('Hanya AP yang dapat menggunakan ini.') apr = self.apr_id - partner_id = apr.user_id.partner_id.id + # partner_id = apr.user_id.partner_id.id + partner_id = apr.applicant_name.partner_id.id ref_label = f'{apr.number} - {apr.detail_note or "-"}' @@ -1496,7 +1498,8 @@ class CreateReimburseCabWizard(models.TransientModel): raise UserError("Tidak ada rincian reimburse yang bisa dijurnalkan.") lines = [] - partner_id = request.user_id.partner_id.id + # partner_id = request.user_id.partner_id.id + partner_id = request.applicant_name.partner_id.id # 1. Buat Jurnal DEBIT dari setiap baris reimburse for line in request.reimburse_line_ids: -- cgit v1.2.3 From 255268563d2b739c5bf4a756614b280067d67050 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 30 Oct 2025 16:01:06 +0700 Subject: (andri) fix label journal --- indoteknik_custom/models/advance_payment_request.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index 66f0aac6..187db257 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -1500,7 +1500,7 @@ class CreateReimburseCabWizard(models.TransientModel): lines = [] # partner_id = request.user_id.partner_id.id partner_id = request.applicant_name.partner_id.id - + ref_label = f'{request.number} - {request.detail_note or "-"}' # 1. Buat Jurnal DEBIT dari setiap baris reimburse for line in request.reimburse_line_ids: if not line.account_id: @@ -1518,12 +1518,11 @@ class CreateReimburseCabWizard(models.TransientModel): lines.append((0, 0, { 'account_id': self.account_id.id, 'partner_id': partner_id, - 'name': f'Reimburse {request.number}', + 'name': ref_label, 'debit': 0, 'credit': request.grand_total_reimburse, })) - ref_label = f'{request.number} - {request.detail_note or "-"}' # 3. Buat Journal Entry move = self.env['account.move'].create({ -- cgit v1.2.3 From d5968a30eaf997b9eaa01f4630fda3f411eaa0b5 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 30 Oct 2025 16:51:21 +0700 Subject: (andri) add user AP --- .../models/advance_payment_request.py | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index 187db257..a1e63403 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -159,7 +159,7 @@ class AdvancePaymentRequest(models.Model): self.nominal = self.grand_total_reimburse def _compute_is_current_user_ap(self): - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] is_ap = self.env.user.id in ap_user_ids for line in self: line.is_current_user_ap = is_ap @@ -372,7 +372,7 @@ class AdvancePaymentRequest(models.Model): def action_view_journal_uangmuka(self): self.ensure_one() - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] if self.env.user.id not in ap_user_ids: raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') @@ -497,7 +497,7 @@ class AdvancePaymentRequest(models.Model): # jakarta_tz = pytz.timezone('Asia/Jakarta') # now = datetime.now(jakarta_tz).replace(tzinfo=None) - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] if self.env.user.id not in ap_user_ids: raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') @@ -572,7 +572,7 @@ class AdvancePaymentRequest(models.Model): ) elif rec.status == 'pengajuan2': - ap_user_ids = [23, 9468] # List user ID yang boleh approve sebagai Finance AP + ap_user_ids = [23, 9468, 16729] # List user ID yang boleh approve sebagai Finance AP if self.env.user.id not in ap_user_ids: raise UserError("Hanya AP yang berhak menyetujui tahap ini.") rec.name_approval_ap = self.env.user.name @@ -614,7 +614,7 @@ class AdvancePaymentRequest(models.Model): def action_ap_only(self): self.ensure_one() - ap_user_ids = [23, 9468] # Ganti sesuai kebutuhan + ap_user_ids = [23, 9468, 16729] # Ganti sesuai kebutuhan if self.env.user.id not in ap_user_ids: raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') @@ -855,7 +855,7 @@ class AdvancePaymentUsageLine(models.Model): ) def _compute_is_current_user_ap(self): - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] is_ap = self.env.user.id in ap_user_ids for line in self: line.is_current_user_ap = is_ap @@ -875,7 +875,7 @@ class AdvancePaymentUsageLine(models.Model): @api.onchange('done_attachment') def _onchange_done_attachment(self): - ap_user_ids = [23, 9468] # List user ID yang boleh approve sebagai Finance AP + ap_user_ids = [23, 9468, 16729] # List user ID yang boleh approve sebagai Finance AP if self.done_attachment and self.env.user.id not in ap_user_ids: self.done_attachment = False @@ -944,7 +944,7 @@ class ReimburseLine(models.Model): ) def _compute_is_current_user_ap(self): - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] is_ap = self.env.user.id in ap_user_ids for line in self: line.is_current_user_ap = is_ap @@ -1081,13 +1081,13 @@ class AdvancePaymentSettlement(models.Model): ) def _compute_is_current_user_ap(self): - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] is_ap = self.env.user.id in ap_user_ids for line in self: line.is_current_user_ap = is_ap def action_toggle_check_attachment(self): - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] if self.env.user.id not in ap_user_ids: raise UserError('Hanya User AP yang dapat menggunakan tombol ini.') @@ -1121,7 +1121,7 @@ class AdvancePaymentSettlement(models.Model): def action_view_journal_uangmuka(self): self.ensure_one() - ap_user_ids = [23, 9468] + ap_user_ids = [23, 9468, 16729] if self.env.user.id not in ap_user_ids: raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') @@ -1185,7 +1185,7 @@ class AdvancePaymentSettlement(models.Model): def action_cab(self): self.ensure_one() - ap_user_ids = [23, 9468] # List user ID yang boleh approve sebagai Finance AP + ap_user_ids = [23, 9468, 16729] # List user ID yang boleh approve sebagai Finance AP if self.env.user.id not in ap_user_ids: raise UserError('Hanya User AP yang dapat menggunakan ini.') if self.move_id: @@ -1311,7 +1311,7 @@ class AdvancePaymentSettlement(models.Model): ) elif rec.status == 'pengajuan2': - ap_user_ids = [23, 9468] # List user ID yang boleh approve sebagai Finance AP + ap_user_ids = [23, 9468, 16729] # List user ID yang boleh approve sebagai Finance AP if self.env.user.id not in ap_user_ids: raise UserError("Hanya AP yang berhak menyetujui tahap ini.") rec.name_approval_ap = self.env.user.name -- cgit v1.2.3 From 88251508d31e0d110dd79ceafe430a0480a10c2b Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 30 Oct 2025 17:34:26 +0700 Subject: (andri) fix note --- indoteknik_custom/models/advance_payment_request.py | 10 ++++++++-- indoteknik_custom/views/advance_payment_settlement.xml | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index a1e63403..c82c09ff 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -989,7 +989,7 @@ class AdvancePaymentSettlement(models.Model): name = fields.Char(string='Nama', readonly=True, tracking=3) title = fields.Char(string='Judul', tracking=3) goals = fields.Text(string='Tujuan', tracking=3) - related = fields.Char(string='Terkait', tracking=3) + related = fields.Char(string='Dok. Terkait', tracking=3) # pemberian_line_ids = fields.One2many( # 'advance.payment.settlement.line', 'realization_id', string='Rincian Pemberian' @@ -1008,7 +1008,13 @@ class AdvancePaymentSettlement(models.Model): # value_down_payment = fields.Float(string='PUM', tracking=3) remaining_value = fields.Float(string='Sisa Uang PUM', tracking=3, compute='_compute_remaining_value') - note_approval = fields.Text(string='Note Persetujuan', tracking=3) + def _get_default_note_approval(self): + template = ( + "Demikian dokumen Realisasi Uang Muka ini saya buat, dengan ini saya meminta persetujuan dibawah atas hasil penggunaan uang muka yang saya gunakan untuk kebutuhan realisasi " + ) + return template + + note_approval = fields.Text(string='Note Persetujuan', tracking=3, default=_get_default_note_approval) name_approval_departement = fields.Char(string='Approval Departement') name_approval_ap = fields.Char(string='Approval AP') diff --git a/indoteknik_custom/views/advance_payment_settlement.xml b/indoteknik_custom/views/advance_payment_settlement.xml index 1a9d7908..188f09d0 100644 --- a/indoteknik_custom/views/advance_payment_settlement.xml +++ b/indoteknik_custom/views/advance_payment_settlement.xml @@ -47,7 +47,9 @@ - + +

*Lengkapi keterangan berikut selaras dengan realisasi yang dilakukan (sesuai dengan format surat yang ada)

+

-- cgit v1.2.3 From 2a57a75b636128cda3d1ee321a926643c461dacf Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 30 Oct 2025 17:51:10 +0700 Subject: (andri) fix --- indoteknik_custom/views/advance_payment_request.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/advance_payment_request.xml b/indoteknik_custom/views/advance_payment_request.xml index 2a8e1318..f8217150 100644 --- a/indoteknik_custom/views/advance_payment_request.xml +++ b/indoteknik_custom/views/advance_payment_request.xml @@ -85,7 +85,7 @@ - + -- cgit v1.2.3 From 4bdebe2972657f95b4d40251121c08acef17ab8a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 31 Oct 2025 10:13:52 +0700 Subject: big fux --- indoteknik_custom/models/sale_order.py | 2 - indoteknik_custom/models/stock_move.py | 117 ++++++++++++++++++++---------- indoteknik_custom/models/stock_picking.py | 15 ++-- indoteknik_custom/views/stock_picking.xml | 6 +- 4 files changed, 93 insertions(+), 47 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index b8de1697..1eba2808 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2722,8 +2722,6 @@ class SaleOrder(models.Model): if self.env.context.get("ask_approval") and user.id in (3401, 20, 3988): return True - - salesperson_id = self.user_id.id approver_id = user.id team_leader_id = self.team_id.user_id.id diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 43c4676e..cac88287 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -186,9 +186,19 @@ class StockMoveLine(models.Model): line_no = fields.Integer('No', default=0) note = fields.Char('Note') manufacture = fields.Many2one('x_manufactures', string="Brands", related="product_id.x_manufacture", store=True) - outstanding_qty = fields.Float( - string='Outstanding Qty', - compute='_compute_delivery_line_status', + qty_yang_mau_dikirim = fields.Float( + string='Qty yang Mau Dikirim', + compute='_compute_delivery_status_detail', + store=False + ) + qty_terkirim = fields.Float( + string='Qty Terkirim', + compute='_compute_delivery_status_detail', + store=False + ) + qty_gantung = fields.Float( + string='Qty Gantung', + compute='_compute_delivery_status_detail', store=False ) delivery_status = fields.Selection([ @@ -196,47 +206,80 @@ class StockMoveLine(models.Model): ('partial', 'Partial'), ('partial_final', 'Partial Final'), ('full', 'Full'), - ], string='Delivery Status', compute='_compute_delivery_line_status', store=False) + ], string='Delivery Status', compute='_compute_delivery_status_detail', store=False) @api.depends('qty_done', 'product_uom_qty', 'picking_id.state') - def _compute_delivery_line_status(self): - for line in self: - line.outstanding_qty = 0.0 - line.delivery_status = 'none' - - picking = line.picking_id - if not picking or picking.picking_type_id.code != 'outgoing': + def _compute_delivery_status_detail(self): + for picking in self: + # Default values + picking.qty_yang_mau_dikirim = 0.0 + picking.qty_terkirim = 0.0 + picking.qty_gantung = 0.0 + picking.delivery_status = 'none' + + # Hanya berlaku untuk pengiriman (BU/OUT) + if picking.picking_id.picking_type_id.code != 'outgoing': continue - total_qty = line.move_id.product_uom_qty or 0 - done_qty = line.qty_done or 0 - - line.outstanding_qty = max(total_qty - done_qty, 0) + if picking.picking_id.name not in ['BU/OUT']: + continue - if total_qty == 0: + move_lines = picking + if not move_lines: continue - if done_qty == 0: - line.delivery_status = 'none' - elif done_qty > 0: - has_other_out = 0 - if picking.group_id and isinstance(picking.id, int): - has_other_out = self.env['stock.picking'].search_count([ - ('group_id', '=', picking.group_id.id), - ('name', 'ilike', 'BU/OUT'), - ('id', '!=', picking.id), - ('state', '=', 'done'), - ]) - if has_other_out and done_qty == total_qty: - line.delivery_status = 'partial_final' - elif not has_other_out and done_qty >= total_qty: - line.delivery_status = 'full' - elif has_other_out and done_qty < total_qty: - line.delivery_status = 'partial' - elif done_qty < total_qty: - line.delivery_status = 'partial' - else: - line.delivery_status = 'none' + # ====================== + # HITUNG QTY + # ====================== + total_qty = move_lines.product_uom_qty + + done_qty_total = move_lines.move_id.sale_line_id.qty_delivered + order_qty_total = move_lines.move_id.sale_line_id.product_uom_qty + gantung_qty_total = order_qty_total - done_qty_total - total_qty + + picking.qty_yang_mau_dikirim = total_qty + picking.qty_terkirim = done_qty_total + picking.qty_gantung = gantung_qty_total + + # if total_qty == 0: + # picking.delivery_status = 'none' + # continue + + # if done_qty_total == 0: + # picking.delivery_status = 'none' + # continue + + # ====================== + # CEK BU/OUT LAIN (BACKORDER) + # ====================== + # has_other_out = self.env['stock.picking'].search_count([ + # ('group_id', '=', picking.group_id.id), + # ('name', 'ilike', 'BU/OUT'), + # ('id', '!=', picking.id), + # ('state', 'in', ['assigned', 'waiting', 'confirmed', 'done']), + # ]) + + # ====================== + # LOGIKA STATUS + # ====================== + if gantung_qty_total == 0 and done_qty_total == 0: + # Semua barang udah terkirim, ga ada picking lain + picking.delivery_status = 'full' + + elif gantung_qty_total > 0 and total_qty > 0 and done_qty_total == 0: + # Masih ada picking lain dan sisa gantung → proses masih jalan + picking.delivery_status = 'partial' + + # elif gantung_qty_total > 0: + # # Ini picking terakhir, tapi qty belum full + # picking.delivery_status = 'partial_final' + + elif gantung_qty_total == 0 and done_qty_total > 0 and total_qty > 0: + # Udah kirim semua tapi masih ada picking lain (rare case) + picking.delivery_status = 'partial_final' + + else: + picking.delivery_status = 'none' # Ambil uom dari stock move @api.model diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 7f8523a3..273fda82 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -212,6 +212,9 @@ class StockPicking(models.Model): if picking.picking_type_id.code != 'outgoing': continue + if picking.name not in ['BU/OUT']: + continue + move_lines = picking.move_line_ids_without_package if not move_lines: continue @@ -240,12 +243,12 @@ class StockPicking(models.Model): # ====================== # CEK BU/OUT LAIN (BACKORDER) # ====================== - has_other_out = self.env['stock.picking'].search_count([ - ('group_id', '=', picking.group_id.id), - ('name', 'ilike', 'BU/OUT'), - ('id', '!=', picking.id), - ('state', 'in', ['assigned', 'waiting', 'confirmed', 'done']), - ]) + # has_other_out = self.env['stock.picking'].search_count([ + # ('group_id', '=', picking.group_id.id), + # ('name', 'ilike', 'BU/OUT'), + # ('id', '!=', picking.id), + # ('state', 'in', ['assigned', 'waiting', 'confirmed', 'done']), + # ]) # ====================== # LOGIKA STATUS diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 050fc819..288a91c9 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -398,8 +398,10 @@ decoration-danger="qty_done>product_uom_qty and state!='done' and parent.picking_type_code != 'incoming'" decoration-success="qty_done==product_uom_qty and state!='done' and not result_package_id"> - - + + + + -- cgit v1.2.3 From c1640e45c37e6ab67cd90e2dbc415989a8a4ad45 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 31 Oct 2025 10:17:45 +0700 Subject: push --- indoteknik_custom/models/stock_move.py | 117 ++++++++++-------------------- indoteknik_custom/views/stock_picking.xml | 8 +- 2 files changed, 41 insertions(+), 84 deletions(-) diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index cac88287..43c4676e 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -186,19 +186,9 @@ class StockMoveLine(models.Model): line_no = fields.Integer('No', default=0) note = fields.Char('Note') manufacture = fields.Many2one('x_manufactures', string="Brands", related="product_id.x_manufacture", store=True) - qty_yang_mau_dikirim = fields.Float( - string='Qty yang Mau Dikirim', - compute='_compute_delivery_status_detail', - store=False - ) - qty_terkirim = fields.Float( - string='Qty Terkirim', - compute='_compute_delivery_status_detail', - store=False - ) - qty_gantung = fields.Float( - string='Qty Gantung', - compute='_compute_delivery_status_detail', + outstanding_qty = fields.Float( + string='Outstanding Qty', + compute='_compute_delivery_line_status', store=False ) delivery_status = fields.Selection([ @@ -206,80 +196,47 @@ class StockMoveLine(models.Model): ('partial', 'Partial'), ('partial_final', 'Partial Final'), ('full', 'Full'), - ], string='Delivery Status', compute='_compute_delivery_status_detail', store=False) + ], string='Delivery Status', compute='_compute_delivery_line_status', store=False) @api.depends('qty_done', 'product_uom_qty', 'picking_id.state') - def _compute_delivery_status_detail(self): - for picking in self: - # Default values - picking.qty_yang_mau_dikirim = 0.0 - picking.qty_terkirim = 0.0 - picking.qty_gantung = 0.0 - picking.delivery_status = 'none' - - # Hanya berlaku untuk pengiriman (BU/OUT) - if picking.picking_id.picking_type_id.code != 'outgoing': - continue + def _compute_delivery_line_status(self): + for line in self: + line.outstanding_qty = 0.0 + line.delivery_status = 'none' - if picking.picking_id.name not in ['BU/OUT']: + picking = line.picking_id + if not picking or picking.picking_type_id.code != 'outgoing': continue - move_lines = picking - if not move_lines: - continue + total_qty = line.move_id.product_uom_qty or 0 + done_qty = line.qty_done or 0 - # ====================== - # HITUNG QTY - # ====================== - total_qty = move_lines.product_uom_qty - - done_qty_total = move_lines.move_id.sale_line_id.qty_delivered - order_qty_total = move_lines.move_id.sale_line_id.product_uom_qty - gantung_qty_total = order_qty_total - done_qty_total - total_qty - - picking.qty_yang_mau_dikirim = total_qty - picking.qty_terkirim = done_qty_total - picking.qty_gantung = gantung_qty_total - - # if total_qty == 0: - # picking.delivery_status = 'none' - # continue - - # if done_qty_total == 0: - # picking.delivery_status = 'none' - # continue - - # ====================== - # CEK BU/OUT LAIN (BACKORDER) - # ====================== - # has_other_out = self.env['stock.picking'].search_count([ - # ('group_id', '=', picking.group_id.id), - # ('name', 'ilike', 'BU/OUT'), - # ('id', '!=', picking.id), - # ('state', 'in', ['assigned', 'waiting', 'confirmed', 'done']), - # ]) - - # ====================== - # LOGIKA STATUS - # ====================== - if gantung_qty_total == 0 and done_qty_total == 0: - # Semua barang udah terkirim, ga ada picking lain - picking.delivery_status = 'full' - - elif gantung_qty_total > 0 and total_qty > 0 and done_qty_total == 0: - # Masih ada picking lain dan sisa gantung → proses masih jalan - picking.delivery_status = 'partial' - - # elif gantung_qty_total > 0: - # # Ini picking terakhir, tapi qty belum full - # picking.delivery_status = 'partial_final' - - elif gantung_qty_total == 0 and done_qty_total > 0 and total_qty > 0: - # Udah kirim semua tapi masih ada picking lain (rare case) - picking.delivery_status = 'partial_final' + line.outstanding_qty = max(total_qty - done_qty, 0) - else: - picking.delivery_status = 'none' + if total_qty == 0: + continue + + if done_qty == 0: + line.delivery_status = 'none' + elif done_qty > 0: + has_other_out = 0 + if picking.group_id and isinstance(picking.id, int): + has_other_out = self.env['stock.picking'].search_count([ + ('group_id', '=', picking.group_id.id), + ('name', 'ilike', 'BU/OUT'), + ('id', '!=', picking.id), + ('state', '=', 'done'), + ]) + if has_other_out and done_qty == total_qty: + line.delivery_status = 'partial_final' + elif not has_other_out and done_qty >= total_qty: + line.delivery_status = 'full' + elif has_other_out and done_qty < total_qty: + line.delivery_status = 'partial' + elif done_qty < total_qty: + line.delivery_status = 'partial' + else: + line.delivery_status = 'none' # Ambil uom dari stock move @api.model diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 288a91c9..78594375 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -398,10 +398,10 @@ decoration-danger="qty_done>product_uom_qty and state!='done' and parent.picking_type_code != 'incoming'" decoration-success="qty_done==product_uom_qty and state!='done' and not result_package_id"> - - - - + + + + -- cgit v1.2.3 From 47b3591071225983cfec5d76497efe5cceae0af6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 31 Oct 2025 10:19:09 +0700 Subject: push --- indoteknik_custom/models/stock_move.py | 117 ++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 43c4676e..cac88287 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -186,9 +186,19 @@ class StockMoveLine(models.Model): line_no = fields.Integer('No', default=0) note = fields.Char('Note') manufacture = fields.Many2one('x_manufactures', string="Brands", related="product_id.x_manufacture", store=True) - outstanding_qty = fields.Float( - string='Outstanding Qty', - compute='_compute_delivery_line_status', + qty_yang_mau_dikirim = fields.Float( + string='Qty yang Mau Dikirim', + compute='_compute_delivery_status_detail', + store=False + ) + qty_terkirim = fields.Float( + string='Qty Terkirim', + compute='_compute_delivery_status_detail', + store=False + ) + qty_gantung = fields.Float( + string='Qty Gantung', + compute='_compute_delivery_status_detail', store=False ) delivery_status = fields.Selection([ @@ -196,47 +206,80 @@ class StockMoveLine(models.Model): ('partial', 'Partial'), ('partial_final', 'Partial Final'), ('full', 'Full'), - ], string='Delivery Status', compute='_compute_delivery_line_status', store=False) + ], string='Delivery Status', compute='_compute_delivery_status_detail', store=False) @api.depends('qty_done', 'product_uom_qty', 'picking_id.state') - def _compute_delivery_line_status(self): - for line in self: - line.outstanding_qty = 0.0 - line.delivery_status = 'none' - - picking = line.picking_id - if not picking or picking.picking_type_id.code != 'outgoing': + def _compute_delivery_status_detail(self): + for picking in self: + # Default values + picking.qty_yang_mau_dikirim = 0.0 + picking.qty_terkirim = 0.0 + picking.qty_gantung = 0.0 + picking.delivery_status = 'none' + + # Hanya berlaku untuk pengiriman (BU/OUT) + if picking.picking_id.picking_type_id.code != 'outgoing': continue - total_qty = line.move_id.product_uom_qty or 0 - done_qty = line.qty_done or 0 - - line.outstanding_qty = max(total_qty - done_qty, 0) + if picking.picking_id.name not in ['BU/OUT']: + continue - if total_qty == 0: + move_lines = picking + if not move_lines: continue - if done_qty == 0: - line.delivery_status = 'none' - elif done_qty > 0: - has_other_out = 0 - if picking.group_id and isinstance(picking.id, int): - has_other_out = self.env['stock.picking'].search_count([ - ('group_id', '=', picking.group_id.id), - ('name', 'ilike', 'BU/OUT'), - ('id', '!=', picking.id), - ('state', '=', 'done'), - ]) - if has_other_out and done_qty == total_qty: - line.delivery_status = 'partial_final' - elif not has_other_out and done_qty >= total_qty: - line.delivery_status = 'full' - elif has_other_out and done_qty < total_qty: - line.delivery_status = 'partial' - elif done_qty < total_qty: - line.delivery_status = 'partial' - else: - line.delivery_status = 'none' + # ====================== + # HITUNG QTY + # ====================== + total_qty = move_lines.product_uom_qty + + done_qty_total = move_lines.move_id.sale_line_id.qty_delivered + order_qty_total = move_lines.move_id.sale_line_id.product_uom_qty + gantung_qty_total = order_qty_total - done_qty_total - total_qty + + picking.qty_yang_mau_dikirim = total_qty + picking.qty_terkirim = done_qty_total + picking.qty_gantung = gantung_qty_total + + # if total_qty == 0: + # picking.delivery_status = 'none' + # continue + + # if done_qty_total == 0: + # picking.delivery_status = 'none' + # continue + + # ====================== + # CEK BU/OUT LAIN (BACKORDER) + # ====================== + # has_other_out = self.env['stock.picking'].search_count([ + # ('group_id', '=', picking.group_id.id), + # ('name', 'ilike', 'BU/OUT'), + # ('id', '!=', picking.id), + # ('state', 'in', ['assigned', 'waiting', 'confirmed', 'done']), + # ]) + + # ====================== + # LOGIKA STATUS + # ====================== + if gantung_qty_total == 0 and done_qty_total == 0: + # Semua barang udah terkirim, ga ada picking lain + picking.delivery_status = 'full' + + elif gantung_qty_total > 0 and total_qty > 0 and done_qty_total == 0: + # Masih ada picking lain dan sisa gantung → proses masih jalan + picking.delivery_status = 'partial' + + # elif gantung_qty_total > 0: + # # Ini picking terakhir, tapi qty belum full + # picking.delivery_status = 'partial_final' + + elif gantung_qty_total == 0 and done_qty_total > 0 and total_qty > 0: + # Udah kirim semua tapi masih ada picking lain (rare case) + picking.delivery_status = 'partial_final' + + else: + picking.delivery_status = 'none' # Ambil uom dari stock move @api.model -- cgit v1.2.3 From d50ce5c3553b97971debedcbb6fe896d99d92081 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 31 Oct 2025 15:45:13 +0700 Subject: balikin --- indoteknik_custom/models/stock_move.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index cac88287..38cf0199 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -22,12 +22,12 @@ class StockMove(models.Model): partial = fields.Boolean('Partial?', default=False) # Ambil product uom dari SO line - @api.model - def create(self, vals): - if vals.get('sale_line_id'): - sale_line = self.env['sale.order.line'].browse(vals['sale_line_id']) - vals['product_uom'] = sale_line.product_uom.id - return super().create(vals) + # @api.model + # def create(self, vals): + # if vals.get('sale_line_id'): + # sale_line = self.env['sale.order.line'].browse(vals['sale_line_id']) + # vals['product_uom'] = sale_line.product_uom.id + # return super().create(vals) # @api.model_create_multi # def create(self, vals_list): @@ -282,10 +282,10 @@ class StockMoveLine(models.Model): picking.delivery_status = 'none' # Ambil uom dari stock move - @api.model - def create(self, vals): - if 'move_id' in vals and 'product_uom_id' not in vals: - move = self.env['stock.move'].browse(vals['move_id']) - if move.product_uom: - vals['product_uom_id'] = move.product_uom.id - return super().create(vals) \ No newline at end of file + # @api.model + # def create(self, vals): + # if 'move_id' in vals and 'product_uom_id' not in vals: + # move = self.env['stock.move'].browse(vals['move_id']) + # if move.product_uom: + # vals['product_uom_id'] = move.product_uom.id + # return super().create(vals) \ No newline at end of file -- cgit v1.2.3 From 58fdd12bb5ea91cbe65f23472879dd690d5efbbf Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Fri, 31 Oct 2025 15:52:49 +0700 Subject: push --- indoteknik_custom/views/refund_sale_order.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml index afa7c1cb..fbe17093 100644 --- a/indoteknik_custom/views/refund_sale_order.xml +++ b/indoteknik_custom/views/refund_sale_order.xml @@ -57,7 +57,7 @@