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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') 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') -- 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 ++-- 3 files changed, 89 insertions(+), 45 deletions(-) (limited to 'indoteknik_custom/models') 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 -- 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 +++++++++++---------------------- 1 file changed, 37 insertions(+), 80 deletions(-) (limited to 'indoteknik_custom/models') 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 -- 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(-) (limited to 'indoteknik_custom/models') 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(-) (limited to 'indoteknik_custom/models') 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 c933cb57a0dbea8ba062a251f28f0a72eb4bb080 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Sat, 1 Nov 2025 07:46:02 +0700 Subject: (andri) it --- indoteknik_custom/models/advance_payment_request.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index c82c09ff..a3a3d20a 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -373,7 +373,8 @@ class AdvancePaymentRequest(models.Model): self.ensure_one() ap_user_ids = [23, 9468, 16729] - if self.env.user.id not in ap_user_ids: + is_it = self.env.user.has_group('indoteknik_custom.group_role_it') + if self.env.user.id not in ap_user_ids and not is_it: raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') if not self.move_id: @@ -1127,8 +1128,9 @@ class AdvancePaymentSettlement(models.Model): def action_view_journal_uangmuka(self): self.ensure_one() - ap_user_ids = [23, 9468, 16729] - if self.env.user.id not in ap_user_ids: + ap_user_ids = [23, 9468, 16729] + is_it = self.env.user.has_group('indoteknik_custom.group_role_it') + if self.env.user.id not in ap_user_ids and not is_it: raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') if not self.move_id: -- cgit v1.2.3 From c0380dd9b5ab6bf6a9538b9fa0c08082095c95fc Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Sat, 1 Nov 2025 09:17:32 +0700 Subject: refudn cancel walaupun udh approved --- indoteknik_custom/models/refund_sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index e6547a88..9eae5b32 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -989,7 +989,7 @@ class RefundSaleOrder(models.Model): for rec in self: if self.env.uid not in allowed_user_ids and not is_fat: raise UserError("❌ Hanya user yang bersangkutan atau Finance (FAT) yang bisa melakukan penolakan.") - if rec.status not in ['refund', 'reject']: + if rec.status != 'reject': rec.status = 'reject' rec.status_payment = 'reject' -- cgit v1.2.3 From 3c552beb2a8bbe51fecff96d3221a4ee1dedbe8f Mon Sep 17 00:00:00 2001 From: Miqdad Date: Sat, 1 Nov 2025 13:16:19 +0700 Subject: remove write validation --- indoteknik_custom/models/tukar_guling_po.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py index 2a5ca3dd..739898a1 100644 --- a/indoteknik_custom/models/tukar_guling_po.py +++ b/indoteknik_custom/models/tukar_guling_po.py @@ -366,8 +366,8 @@ class TukarGulingPO(models.Model): # if bu_put: # raise UserError("❌ Tidak bisa retur BU/INPUT karena BU/PUT sudah Done!") - if self.operations.picking_type_id.id == 28 and tipe == 'tukar_guling': - raise UserError("❌ BU/INPUT tidak boleh di retur tukar guling") + # if self.operations.picking_type_id.id == 28 and tipe == 'tukar_guling': + # raise UserError("❌ BU/INPUT tidak boleh di retur tukar guling") # if self.operations.picking_type_id.id != 28: # if self._is_already_returned(self.operations): -- cgit v1.2.3 From d636c09592c484fddd436e6881c5052fd06c028a Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 3 Nov 2025 09:00:23 +0700 Subject: add so num in transfer --- indoteknik_custom/models/stock_picking.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 273fda82..c17fdbd5 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -198,6 +198,14 @@ class StockPicking(models.Model): ('partial_final', 'Partial Final'), ('full', 'Full'), ], string='Delivery Status', compute='_compute_delivery_status_detail', store=False) + so_num = fields.Char('SO Number', compute='_get_so_num') + + @api.depends('group_id') + def _get_so_num(self): + for record in self: + record.so_num = record.group_id.name + + @api.depends('move_line_ids_without_package.qty_done', 'move_line_ids_without_package.product_uom_qty', 'state') def _compute_delivery_status_detail(self): -- cgit v1.2.3 From 215411bc6cf4413941f978e4bf4d2f0658f8bd58 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 3 Nov 2025 12:06:14 +0700 Subject: uom coretax id --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/uom_uom.py | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 indoteknik_custom/models/uom_uom.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 165dae4e..6e1ef2e0 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -163,3 +163,4 @@ from . import letter_receivable from . import sj_tele from . import partial_delivery from . import domain_apo +from . import uom_uom \ No newline at end of file diff --git a/indoteknik_custom/models/uom_uom.py b/indoteknik_custom/models/uom_uom.py new file mode 100644 index 00000000..32e53d73 --- /dev/null +++ b/indoteknik_custom/models/uom_uom.py @@ -0,0 +1,6 @@ +from odoo import fields, models, api, _ + +class Uom(models.Model): + _inherit = 'uom.uom' + + coretax_id = fields.Char(string='Coretax ID') -- cgit v1.2.3 From 0bb7e8ff5eafa5dbc218d547999876bb11e05c69 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 3 Nov 2025 16:14:12 +0700 Subject: push --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 534d8122..c2b15078 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1123,7 +1123,7 @@ class PurchaseOrder(models.Model): if not self.not_update_purchasepricelist: self.add_product_to_pricelist() for line in self.order_line: - if not line.product_id.public_categ_ids: + if line.product_id.type == 'product' and not line.product_id.categ_id: raise UserError("Product %s kategorinya kosong" % line.product_id.name) if not line.product_id.purchase_ok: raise UserError("Terdapat barang yang tidak bisa diproses") -- cgit v1.2.3 From d3626a4773647ef1910b66fcc8c981dcab562c65 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 4 Nov 2025 15:20:18 +0700 Subject: (andri) add cbd lock date & fix seq PUM reimburse --- indoteknik_custom/models/res_partner.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index ef1a5cf4..f80bbcb6 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -182,6 +182,7 @@ class ResPartner(models.Model): payment_history_url = fields.Text(string='Payment History URL') is_cbd_locked = fields.Boolean("Locked to CBD?", default=False, tracking=True, help="Jika dicentang, maka partner ini terkunci pada payment term CBD karena memiliki invoice yang sudah jatuh tempo lebih dari 30 hari.") + cbd_lock_date = fields.Datetime("CBD Lock Date", tracking=True, help="Tanggal ketika partner ini dikunci pada payment term CBD.") @api.model -- cgit v1.2.3 From cabe184a38a6a96b9557ff7debb2e9165894a7b6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 5 Nov 2025 14:43:55 +0700 Subject: push --- indoteknik_custom/models/sale_order.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 1eba2808..d7b0ccee 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2342,11 +2342,6 @@ class SaleOrder(models.Model): # return self._create_notification_action('Notification', # 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension') - if not order.with_context(ask_approval=True)._is_request_to_own_team_leader(): - return self._create_notification_action( - 'Peringatan', - 'Hanya bisa konfirmasi SO tim Anda.' - ) if order._requires_approval_margin_leader(): order.approval_status = 'pengajuan2' return self._create_approval_notification('Pimpinan') @@ -2362,6 +2357,12 @@ class SaleOrder(models.Model): self.check_limit_so_to_invoice() order.approval_status = 'pengajuan1' return self._create_approval_notification('Team Sales') + + if not order.with_context(ask_approval=True)._is_request_to_own_team_leader(): + return self._create_notification_action( + 'Peringatan', + 'Hanya bisa konfirmasi SO tim Anda.' + ) raise UserError("Bisa langsung Confirm") @@ -2716,11 +2717,12 @@ class SaleOrder(models.Model): if user.is_leader or user.is_sales_manager: return True + if self.env.context.get("ask_approval") and user.id in (3401, 20, 3988): + return True + 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 89fe1e885966d46b1e96829d3ecc1c009e0514b8 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 5 Nov 2025 18:15:14 +0700 Subject: disable show description for PO altama --- indoteknik_custom/models/purchase_order.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index c2b15078..b9211276 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -118,9 +118,18 @@ class PurchaseOrder(models.Model): show_description = fields.Boolean( string='Show Description', - default=True + compute='_compute_show_description' ) - + + @api.depends('show_description') + def _compute_show_description(self): + for order in self: + # Show desc false for altama only + if order.partner_id == 5571: + order.show_description = False + else: + order.show_description = True + @api.onchange('show_description') def onchange_show_description(self): if self.show_description == True: -- cgit v1.2.3 From 3ff3ddc67d4664871314462fb184a6fe369f3a63 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 5 Nov 2025 18:54:45 +0700 Subject: disable show description for PO altama --- indoteknik_custom/models/purchase_order.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index b9211276..8772dea9 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -118,17 +118,17 @@ class PurchaseOrder(models.Model): show_description = fields.Boolean( string='Show Description', - compute='_compute_show_description' + compute='_compute_show_description', + default=True ) - @api.depends('show_description') + @api.depends('partner_id') def _compute_show_description(self): for order in self: - # Show desc false for altama only - if order.partner_id == 5571: + if order.partner_id.id == 5571: order.show_description = False else: - order.show_description = True + order.show_description = order.show_description @api.onchange('show_description') def onchange_show_description(self): -- cgit v1.2.3 From ddc06e464075c316de8f236e0e037dd964a972e3 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 10:16:52 +0700 Subject: add new field --- indoteknik_custom/models/stock_picking.py | 44 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index c17fdbd5..04847be8 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -89,6 +89,7 @@ class StockPicking(models.Model): readonly=True, related="id", ) + sj_documentations = fields.One2many('stock.picking.sj.document','picking_id', string='Dokumentasi SJ (Multi)') sj_documentation = fields.Binary(string="Dokumentasi Surat Jalan") paket_documentation = fields.Binary(string="Dokumentasi Paket") dispatch_documentation = fields.Binary(string="Dokumentasi Dispatch") @@ -205,8 +206,6 @@ class StockPicking(models.Model): for record in self: record.so_num = record.group_id.name - - @api.depends('move_line_ids_without_package.qty_done', 'move_line_ids_without_package.product_uom_qty', 'state') def _compute_delivery_status_detail(self): for picking in self: @@ -468,7 +467,6 @@ class StockPicking(models.Model): except ValueError: return False - def action_get_kgx_pod(self, shipment=False): self.ensure_one() @@ -1189,7 +1187,8 @@ class StockPicking(models.Model): self.sale_id.date_doc_kirim = self.date_doc_kirim def action_assign(self): - if self.env.context.get('default_picking_type_id') and ('BU/INPUT' not in self.name or 'BU/PUT' not in self.name): + if self.env.context.get('default_picking_type_id') and ( + 'BU/INPUT' not in self.name or 'BU/PUT' not in self.name): pickings_to_assign = self.filtered( lambda p: not (p.sale_id and p.sale_id.hold_outgoing) ) @@ -1205,18 +1204,15 @@ class StockPicking(models.Model): return res - def ask_approval(self): # if self.env.user.is_accounting: # if self.env.user.is_accounting and self.location_id.id == 57 or self.location_id == 57 and self.approval_status in ['pengajuan1', ''] and 'BU/IU' in self.name and self.approval_status == 'pengajuan1': # raise UserError("Bisa langsung set ke approval logistik") if self.env.user.is_accounting and self.approval_status == "pengajuan2" and 'BU/IU' in self.name: raise UserError("Tidak perlu ask approval sudah approval logistik") - if self.env.user.is_logistic_approver and self.location_id.id == 57 or self.location_id== 57 and self.approval_status == 'pengajuan2' and 'BU/IU' in self.name: + if self.env.user.is_logistic_approver and self.location_id.id == 57 or self.location_id == 57 and self.approval_status == 'pengajuan2' and 'BU/IU' in self.name: raise UserError("Bisa langsung Validate") - - # for calendar distribute only # if self.is_internal_use: # stock_move_lines = self.env['stock.move.line'].search([ @@ -1239,7 +1235,6 @@ class StockPicking(models.Model): raise UserError("Qty tidak boleh 0") pick.approval_status = 'pengajuan1' - def ask_receipt_approval(self): if self.env.user.is_logistic_approver: raise UserError('Bisa langsung validate tanpa Ask Receipt') @@ -1405,7 +1400,7 @@ class StockPicking(models.Model): and self.create_date > threshold_datetime and not self.so_lama): raise UserError(_("Tidak ada scan koli! Harap periksa kembali.")) - + if 'BU/OUT/' in self.name: self.driver_departure_date = datetime.datetime.utcnow() @@ -1447,13 +1442,16 @@ class StockPicking(models.Model): # if self.is_internal_use and not self.env.user.is_logistic_approver and self.location_id.id == 57 and self.approval_status == 'pengajuan2': # raise UserError("Harus di Approve oleh Logistik") - if self.is_internal_use and self.approval_status in ['pengajuan1', '', False] and 'BU/IU' in self.name and self.is_bu_iu == True: + if self.is_internal_use and self.approval_status in ['pengajuan1', '', + False] and 'BU/IU' in self.name and self.is_bu_iu == True: raise UserError("Tidak Bisa Validate, set approval status ke approval logistik terlebih dahhulu") - if self.is_internal_use and not self.env.user.is_logistic_approver and self.approval_status in ['pengajuan2'] and self.is_bu_iu == True and 'BU/IU' in self.name: + if self.is_internal_use and not self.env.user.is_logistic_approver and self.approval_status in [ + 'pengajuan2'] and self.is_bu_iu == True and 'BU/IU' in self.name: raise UserError("Harus di Approve oleh Logistik") - if self.is_internal_use and not self.env.user.is_accounting and self.approval_status in ['pengajuan1', '', False] and self.is_bu_iu == False: + if self.is_internal_use and not self.env.user.is_accounting and self.approval_status in ['pengajuan1', '', + False] and self.is_bu_iu == False: raise UserError("Harus di Approve oleh Accounting") if self.picking_type_id.id == 28 and not self.env.user.is_logistic_approver: @@ -1479,7 +1477,6 @@ class StockPicking(models.Model): current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.date_reserved = current_time - # Validate Qty Demand Can't higher than Qty Product if self.location_dest_id.id == 58 and 'BU/INPUT/' in self.name: for move in self.move_ids_without_package: @@ -1880,7 +1877,8 @@ class StockPicking(models.Model): 'name': move_line.product_id.name, 'code': move_line.product_id.default_code, 'qty': move_line.qty_done, - 'image': self.env['ir.attachment'].api_image('product.template', 'image_128', move_line.product_id.product_tmpl_id.id), + 'image': self.env['ir.attachment'].api_image('product.template', 'image_128', + move_line.product_id.product_tmpl_id.id), }) response = { @@ -2246,7 +2244,6 @@ class CheckProduct(models.Model): _order = 'picking_id, id' _inherit = ['barcodes.barcode_events_mixin'] - picking_id = fields.Many2one( 'stock.picking', string='Picking Reference', @@ -2699,8 +2696,6 @@ class ScanKoli(models.Model): out_move.qty_done += qty_to_assign qty_koli -= qty_to_assign - - def _reset_qty_done_if_no_scan(self, picking_id): product_bu_pick = self.env['stock.move.line'].search([('picking_id', '=', picking_id)]) @@ -2759,4 +2754,15 @@ class WarningModalWizard(models.TransientModel): def action_continue(self): if self.picking_id: return self.picking_id.with_context(skip_koli_check=True).button_validate() - return {'type': 'ir.actions.act_window_close'} \ No newline at end of file + return {'type': 'ir.actions.act_window_close'} + + +class StockPickingSjDocument(models.Model): + _name = 'stock.picking.sj.document' + _description = 'Dokumentasi Surat Jalan (Multi)' + _order = 'sequence, id' + _rec_name = 'id' + + picking_id = fields.Many2one('stock.picking', required=True, ondelete='cascade') + image = fields.Binary('Gambar', required=True, attachment=True) + sequence = fields.Integer('Urutan', default=10) \ No newline at end of file -- cgit v1.2.3 From be3c90b805dec1e178aa8cd70c187c79e3dd8443 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 10:39:21 +0700 Subject: cr ask approval admin --- indoteknik_custom/models/sale_order.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d7b0ccee..ff79761c 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2363,6 +2363,15 @@ class SaleOrder(models.Model): 'Peringatan', 'Hanya bisa konfirmasi SO tim Anda.' ) + if self.env.user.id in (3401, 20, 3988, 17340): + if self.total_percent_margin <= 15: + self._requires_approval_margin_leader() + self.approval_status = 'pengajuan2' + elif self.total_percent_margin < 18: + self._requires_approval_margin_manager() + self.approval_status = 'pengajuan1' + elif 18 <= self.total_percent_margin <= 24: + self._requires_approval_team_sales() raise UserError("Bisa langsung Confirm") -- cgit v1.2.3 From 73908f6f60b4c5f3d7b7cd3a1a3ab04495de2047 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 13:38:58 +0700 Subject: cr ask approval admin --- indoteknik_custom/models/sale_order.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ff79761c..73af811b 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2363,15 +2363,6 @@ class SaleOrder(models.Model): 'Peringatan', 'Hanya bisa konfirmasi SO tim Anda.' ) - if self.env.user.id in (3401, 20, 3988, 17340): - if self.total_percent_margin <= 15: - self._requires_approval_margin_leader() - self.approval_status = 'pengajuan2' - elif self.total_percent_margin < 18: - self._requires_approval_margin_manager() - self.approval_status = 'pengajuan1' - elif 18 <= self.total_percent_margin <= 24: - self._requires_approval_team_sales() raise UserError("Bisa langsung Confirm") @@ -2712,7 +2703,7 @@ class SaleOrder(models.Model): def _requires_approval_team_sales(self): return ( - 18 <= self.total_percent_margin <= 24 + self.total_percent_margin >= 18 and self.env.user.id not in [11, 9, 375] # Eko, Ade, Putra and not self.env.user.is_sales_manager and not self.env.user.is_leader -- cgit v1.2.3 From af30e94cff35eec4b71cb89fbe7a9a4f654480cb Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 13:40:28 +0700 Subject: cr ask approval admin --- indoteknik_custom/models/sale_order.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ff79761c..1d07a1ff 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2363,15 +2363,6 @@ class SaleOrder(models.Model): 'Peringatan', 'Hanya bisa konfirmasi SO tim Anda.' ) - if self.env.user.id in (3401, 20, 3988, 17340): - if self.total_percent_margin <= 15: - self._requires_approval_margin_leader() - self.approval_status = 'pengajuan2' - elif self.total_percent_margin < 18: - self._requires_approval_margin_manager() - self.approval_status = 'pengajuan1' - elif 18 <= self.total_percent_margin <= 24: - self._requires_approval_team_sales() raise UserError("Bisa langsung Confirm") @@ -2712,7 +2703,8 @@ class SaleOrder(models.Model): def _requires_approval_team_sales(self): return ( - 18 <= self.total_percent_margin <= 24 + # 18 <= self.total_percent_margin <= 24 + self.total_percent_margin >= 18 and self.env.user.id not in [11, 9, 375] # Eko, Ade, Putra and not self.env.user.is_sales_manager and not self.env.user.is_leader -- cgit v1.2.3 From dd51ce73e27cd7639b512a219e7bc68bb467b4d3 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 15:04:05 +0700 Subject: show desc false altama --- indoteknik_custom/models/automatic_purchase.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index d9ec17f4..012d680a 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -239,7 +239,8 @@ class AutomaticPurchase(models.Model): 'picking_type_id': 28, 'date_order': current_time, 'from_apo': True, - 'note_description': 'Automatic PO' + 'note_description': 'Automatic PO', + 'show_description': False if vendor_id.id == 5571 else True, } new_po = self.env['purchase.order'].create(param_header) -- cgit v1.2.3 From 449a3f3a3acaeb0b950f57daee1067d70d483d90 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 15:04:16 +0700 Subject: show desc false altama --- indoteknik_custom/models/purchase_order.py | 8 -------- 1 file changed, 8 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 8772dea9..4475e777 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -118,17 +118,9 @@ class PurchaseOrder(models.Model): show_description = fields.Boolean( string='Show Description', - compute='_compute_show_description', default=True ) - @api.depends('partner_id') - def _compute_show_description(self): - for order in self: - if order.partner_id.id == 5571: - order.show_description = False - else: - order.show_description = order.show_description @api.onchange('show_description') def onchange_show_description(self): -- cgit v1.2.3 From ee9706c1f34c88ca2cfc32dbe7a90c38731166b1 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 15:12:45 +0700 Subject: show desc false altama --- indoteknik_custom/models/automatic_purchase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 012d680a..ce0328c4 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -240,7 +240,7 @@ class AutomaticPurchase(models.Model): 'date_order': current_time, 'from_apo': True, 'note_description': 'Automatic PO', - 'show_description': False if vendor_id.id == 5571 else True, + 'show_description': False if vendor_id == 5571 else True, } new_po = self.env['purchase.order'].create(param_header) -- cgit v1.2.3 From 3f905516b4b0b6573ebdf67f18582f20b023f7f6 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 6 Nov 2025 16:32:57 +0700 Subject: update --- indoteknik_custom/models/sale_order.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 1d07a1ff..31662fb4 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2597,7 +2597,7 @@ class SaleOrder(models.Model): order.approval_status = 'pengajuan1' return self._create_approval_notification('Sales Manager') elif order._requires_approval_team_sales(): - order.approval_status = 'pengajuan1' + # order.approval_status = 'pengajuan1' return self._create_approval_notification('Team Sales') order.approval_status = 'approved' @@ -2703,8 +2703,8 @@ class SaleOrder(models.Model): def _requires_approval_team_sales(self): return ( - # 18 <= self.total_percent_margin <= 24 - self.total_percent_margin >= 18 + 18 <= self.total_percent_margin <= 24 + # self.total_percent_margin >= 18 and self.env.user.id not in [11, 9, 375] # Eko, Ade, Putra and not self.env.user.is_sales_manager and not self.env.user.is_leader -- cgit v1.2.3 From 459e34a6f96ed12522036bb12da2e0488581c016 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 7 Nov 2025 13:16:34 +0700 Subject: CR nathan stock picking --- indoteknik_custom/models/sale_order.py | 1 + indoteknik_custom/models/stock_picking.py | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 31662fb4..ef6318da 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -398,6 +398,7 @@ class SaleOrder(models.Model): compute="_compute_partner_is_cbd_locked" ) internal_notes_contact = fields.Text(related='partner_id.comment', string="Internal Notes", readonly=True, help="Internal Notes dari contact utama customer.") + is_so_fiktif = fields.Boolean('SO Fiktif?') def action_open_partial_delivery_wizard(self): # raise UserError("Fitur ini sedang dalam pengembangan") diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index c17fdbd5..8fefcf81 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -199,14 +199,19 @@ class StockPicking(models.Model): ('full', 'Full'), ], string='Delivery Status', compute='_compute_delivery_status_detail', store=False) so_num = fields.Char('SO Number', compute='_get_so_num') + is_so_fiktif = fields.Boolean('SO Fiktif?', compute='_compute_is_so_fiktif') + + @api.depends('sale_id.is_so_fiktif') + def _compute_is_so_fiktif(self): + for picking in self: + picking.is_so_fiktif = picking.sale_id.is_so_fiktif if picking.sale_id else False + @api.depends('group_id') def _get_so_num(self): for record in self: record.so_num = record.group_id.name - - @api.depends('move_line_ids_without_package.qty_done', 'move_line_ids_without_package.product_uom_qty', 'state') def _compute_delivery_status_detail(self): for picking in self: @@ -1383,6 +1388,8 @@ class StockPicking(models.Model): group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])]) active_model = self.env.context.get('active_model') + if self.is_so_fiktif == True: + raise UserError("SO Fiktif tidak bisa di validate") if self.location_id.id == 47 and self.env.user.id not in users_in_group.mapped( 'id') and self.state_approve_md != 'done': self.state_approve_md = 'waiting' if self.state_approve_md != 'pending' else 'pending' @@ -1562,6 +1569,10 @@ class StockPicking(models.Model): elif self.tukar_guling_po_id: self.tukar_guling_po_id.update_doc_state() + user = self.env.user + if not user.has_group('indoteknik_custom.group_role_logistic'): + raise UserWarning('Validate hnaya bisa di lakukan oleh logistik') + return res def automatic_reserve_product(self): @@ -1732,6 +1743,13 @@ class StockPicking(models.Model): 'indoteknik_custom.group_role_logistic') and self.picking_type_code == 'outgoing': raise UserError("Button ini hanya untuk Logistik") + if len(self.check_product_lines) >= 1: + raise UserError("Tidak Bisa cancel karena sudah di check product") + + if not self.env.user.is_logistic_approver and not self.env.user.has_group('indoteknik_custom.group_role_logistic'): + if self.name and ('BU/PICK' in self.name or 'BU/OUT' in self.name or 'BU/ORT' in self.name or 'BU/SRT' in self.name): + raise UserError("Button ini hanya untuk Logistik") + res = super(StockPicking, self).action_cancel() return res -- cgit v1.2.3 From f0931f9b846f05a4debc967597bb54f91f9b640a Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 7 Nov 2025 14:53:25 +0700 Subject: get image from envio --- indoteknik_custom/models/stock_picking.py | 35 +++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 8fefcf81..798b4109 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -5,16 +5,16 @@ from collections import defaultdict from datetime import timedelta, datetime from datetime import timedelta, datetime as waktu from itertools import groupby -import pytz, requests, json, requests +import pytz, json from dateutil import parser import datetime import hmac import hashlib -import base64 import requests import time import logging import re +import base64 _logger = logging.getLogger(__name__) @@ -823,6 +823,37 @@ class StockPicking(models.Model): picking.envio_cod_value = data.get("cod_value", 0.0) picking.envio_cod_status = data.get("cod_status") + images_data = data.get('images', []) + for img in images_data: + image_url = img.get('image') + if image_url: + try: + # Download image from URL + img_response = requests.get(image_url) + img_response.raise_for_status() + + # Encode image to base64 + image_base64 = base64.b64encode(img_response.content) + + # Create attachment in Odoo + attachment = self.env['ir.attachment'].create({ + 'name': 'Envio Image', + 'type': 'binary', + 'datas': image_base64, + 'res_model': picking._name, + 'res_id': picking.id, + 'mimetype': 'image/png', + }) + + # Post log note with attachment + picking.message_post( + body="Image Envio", + attachment_ids=[attachment.id] + ) + + except Exception as e: + picking.message_post(body=f"Gagal ambil image Envio: {str(e)}") + # Menyimpan log terbaru logs = data.get("logs", []) if logs and isinstance(logs, list) and logs[0]: -- cgit v1.2.3 From e8812897c981a55130c452cc15600a4758ffcffb Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 7 Nov 2025 15:30:15 +0700 Subject: fix date approve --- indoteknik_custom/models/commision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py index a937e2d0..441dd54f 100644 --- a/indoteknik_custom/models/commision.py +++ b/indoteknik_custom/models/commision.py @@ -423,8 +423,8 @@ class CustomerCommision(models.Model): def action_confirm_customer_commision(self): jakarta_tz = pytz.timezone('Asia/Jakarta') now = datetime.now(jakarta_tz) - - now_naive = now.replace(tzinfo=None) + now_utc = now.astimezone(pytz.utc) + now_naive = now_utc.replace(tzinfo=None) if not self.status or self.status == 'draft': self.status = 'pengajuan1' -- cgit v1.2.3 From 2cc12f95a1fbc0de8018446cd5e23a35ac892494 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 7 Nov 2025 17:48:14 +0700 Subject: fix error cancel SO --- indoteknik_custom/models/stock_picking.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 798b4109..0178ac33 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1778,8 +1778,10 @@ class StockPicking(models.Model): raise UserError("Tidak Bisa cancel karena sudah di check product") if not self.env.user.is_logistic_approver and not self.env.user.has_group('indoteknik_custom.group_role_logistic'): - if self.name and ('BU/PICK' in self.name or 'BU/OUT' in self.name or 'BU/ORT' in self.name or 'BU/SRT' in self.name): - raise UserError("Button ini hanya untuk Logistik") + for picking in self: + if picking.name and ('BU/PICK' in picking.name or 'BU/OUT' in picking.name or 'BU/ORT' in picking.name or 'BU/SRT' in picking.name): + if picking.state not in ['cancel']: + raise UserError("Button ini hanya untuk Logistik") res = super(StockPicking, self).action_cancel() return res -- cgit v1.2.3 From bb7121ab8a7dbdfb104eefbeddc9fb6d4383054b Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Sat, 8 Nov 2025 11:00:09 +0700 Subject: initial commit for branch feature/komisi-sales-internal --- indoteknik_custom/models/__init__.py | 3 +- indoteknik_custom/models/commission_internal.py | 129 ++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/commission_internal.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 6e1ef2e0..a14c766e 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -163,4 +163,5 @@ from . import letter_receivable from . import sj_tele from . import partial_delivery from . import domain_apo -from . import uom_uom \ No newline at end of file +from . import uom_uom +from . import commission_internal diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py new file mode 100644 index 00000000..8a333bda --- /dev/null +++ b/indoteknik_custom/models/commission_internal.py @@ -0,0 +1,129 @@ +from odoo import models, api, fields +from odoo.exceptions import AccessError, UserError, ValidationError +from datetime import timedelta, date +import logging + +_logger = logging.getLogger(__name__) + + +class CommissionInternal(models.Model): + _name = 'commission.internal' + _description = 'Commission Internal' + _order = 'date_doc, id desc' + _inherit = ['mail.thread'] + _rec_name = 'number' + + number = fields.Char(string='Document No', index=True, copy=False, readonly=True) + date_doc = fields.Date(string='Document Date', required=True) + month = fields.Selection([ + ('01', 'January'), ('02', 'February'), ('03', 'March'), + ('04', 'April'), ('05', 'May'), ('06', 'June'), + ('07', 'July'), ('08', 'August'), ('09', 'September'), + ('10', 'October'), ('11', 'November'), ('12', 'December') + ], string="Commission Month") + year = fields.Selection([(str(y), str(y)) for y in range(2025, 2036)], string="Commission Year") + description = fields.Char(string='Description') + comment = fields.Char(string='Comment') + commission_internal_line = fields.One2many('commission.internal.line', 'commission_internal_id', string='Lines', + auto_join=True, order='account_move_id asc') + + @api.model + def create(self, vals): + vals['number'] = self.env['ir.sequence'].next_by_code('commission.internal') or '0' + result = super(CommissionInternal, self).create(vals) + return result + + def _get_commission_internal_bank_account_ids(self): + bank_ids = self.env['ir.config_parameter'].sudo().get_param('commission.internal.bank.account.id') + if not bank_ids: + return [] + return [int(x.strip()) for x in bank_ids.split(',') if x.strip().isdigit()] + + def _get_period_range(self, period_year, period_month): + """Return (date_start, date_end) using separate year and month fields.""" + self.ensure_one() # make sure it's called on a single record + + year_str = period_year or '' + month_str = period_month or '' + + # Validate both fields exist + if not (year_str.isdigit() and month_str.isdigit()): + return None, None + + year = int(year_str) + month = int(month_str) + + # First day of this month + dt_start = date(year, month, 1) + + # Compute first day of next month + if month == 12: + next_month = date(year + 1, 1, 1) + else: + next_month = date(year, month + 1, 1) + + # Last day = one day before next month's first day + dt_end = next_month - timedelta(days=1) + + return dt_start, dt_end + + def generate_commission_from_generate_ledger(self): + if self.commission_internal_line: + raise UserError('Harus hapus semua line jika ingin generate ulang') + if not self.month: + raise UserError('Commission Month harus diisi') + if not self.year: + raise UserError('Commission Year harus diisi') + + dt_start, dt_end = self._get_period_range(self.year, self.month) + + account_bank_ids = self._get_commission_internal_bank_account_ids() + query = [ + ('move_id.state', '=', 'posted'), + ('account_id', 'in', account_bank_ids), + ('date', '>=', dt_start), + ('date', '<=', dt_end) + ] + ledgers = self.env['account.move.line'].search(query) + count = 0 + for ledger in ledgers: + _logger.info("Read General Ledger Account Move Line %s" % ledger.id) + self.env['commission.internal.line'].create([{ + 'commission_internal_id': self.id, + 'date': ledger.date, + 'number': ledger.move_id.name, + 'account_move_id': ledger.move_id.id, + 'account_move_line_id': ledger.id, + 'account_id': ledger.account_id.id, + 'label': ledger.name, + 'debit': ledger.debit, + 'credit': ledger.credit, + 'balance': ledger.balance + }]) + count += 1 + _logger.info("Commission Internal Line generated %s" % count) + + +class CommissionInternalLine(models.Model): + _name = 'commission.internal.line' + _description = 'Line' + _order = 'number asc, id' + + commission_internal_id = fields.Many2one('commission.internal', string='Internal Ref', required=True, + ondelete='cascade', index=True, copy=False) + date = fields.Date(string='Date') + number = fields.Char(string='Number') + account_move_id = fields.Many2one('account.move', string='Account Move') + account_move_line_id = fields.Many2one('account.move.line', string='Account Move Line') + account_id = fields.Many2one('account.account', string='Account') + label = fields.Char(string='Label') + debit = fields.Float(string='Debit') + credit = fields.Float(string='Credit') + balance = fields.Float(string='Balance') + ongkir = fields.Float(string='Ongkir') + refund = fields.Float(string='Refund') + pph = fields.Float(string='PPh23') + others = fields.Float(string='Others') + linenetamt = fields.Float(string='Net Amount') + dpp = fields.Float(string='DPP') + status = fields.Char(string='Status') -- cgit v1.2.3 From 7efc5a1a9b0f8a8479a9fed03577a76bdba8af22 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Sat, 8 Nov 2025 19:27:23 +0700 Subject: sync real deliv and deliv addr to stock picking (pick & out) --- indoteknik_custom/models/sale_order.py | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ef6318da..bc33e8e6 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -400,6 +400,44 @@ class SaleOrder(models.Model): internal_notes_contact = fields.Text(related='partner_id.comment', string="Internal Notes", readonly=True, help="Internal Notes dari contact utama customer.") is_so_fiktif = fields.Boolean('SO Fiktif?') + def action_set_shipping_id(self): + for rec in self: + bu_pick = self.env['stock.picking'].search([ + ('state', 'not in', ['cancel']), + ('picking_type_id', '=', 30), + ('sale_id', '=', rec.id), + ('linked_manual_bu_out', '=', False) + ]) + # bu_out = bu_pick_has_out.mapped('linked_manual_bu_out') + bu_out = self.env['stock.picking'].search([ + ('sale_id', '=', rec.id), + ('picking_type_id', '=', 29), + ('state', 'not in', ['cancel', 'done']) + ]) + bu_pick_has_out = self.env['stock.picking'].search([ + ('state', 'not in', ['cancel']), + ('picking_type_id', '=', 30), + ('sale_id', '=', rec.id), + ('linked_manual_bu_out.id', '=', bu_out.id), + ('linked_manual_bu_out.state', 'not in', ['done', 'cancel']) + ]) + for pick in bu_pick_has_out: + linked_out = pick.linked_manual_bu_out + if pick.real_shipping_id != rec.real_shipping_id or linked_out.partner_id != rec.partner_shipping_id: + pick.real_shipping_id = rec.real_shipping_id + pick.partner_id = rec.partner_shipping_id + linked_out.partner_id = rec.partner_shipping_id + linked_out.real_shipping_id = rec.real_shipping_id + _logger.info('Updated bu_pick [%s] and bu_out [%s]', pick.name, linked_out.name) + + for pick in bu_pick: + if pick.real_shipping_id != rec.real_shipping_id: + pick.real_shipping_id = rec.real_shipping_id + pick.partner_id = rec.partner_shipping_id + bu_out.partner_id = rec.partner_shipping_id + bu_out.real_shipping_id = rec.real_shipping_id + _logger.info('Updated bu_pick [%s] without bu_out', pick.name) + def action_open_partial_delivery_wizard(self): # raise UserError("Fitur ini sedang dalam pengembangan") self.ensure_one() @@ -3377,6 +3415,9 @@ class SaleOrder(models.Model): # if updated_vals: # line.write(updated_vals) + + if 'real_shipping_id' in vals: + self.action_set_shipping_id() return res def button_refund(self): -- cgit v1.2.3 From 1554163f079ad816279ddbf2a244327e4e0b89c1 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Sat, 8 Nov 2025 21:06:42 +0700 Subject: set uom faktur xml based on coretax id --- indoteknik_custom/models/coretax_fatur.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/coretax_fatur.py b/indoteknik_custom/models/coretax_fatur.py index ce94306f..7e0de919 100644 --- a/indoteknik_custom/models/coretax_fatur.py +++ b/indoteknik_custom/models/coretax_fatur.py @@ -147,6 +147,8 @@ class CoretaxFaktur(models.Model): subtotal = line_price_subtotal quantity = line_quantity total_discount = round(line_discount, 2) + coretax_id = line.product_uom_id.coretax_id + uom_name = line.product_uom_id.name # Calculate other tax values otherTaxBase = round(subtotal * (11 / 12), 2) if subtotal else 0 @@ -159,7 +161,7 @@ class CoretaxFaktur(models.Model): ET.SubElement(good_service, 'Opt').text = 'A' ET.SubElement(good_service, 'Code').text = '000000' ET.SubElement(good_service, 'Name').text = line_name - ET.SubElement(good_service, 'Unit').text = 'UM.0018' + ET.SubElement(good_service, uom_name).text = coretax_id # ET.SubElement(good_service, 'Price').text = str(round(line_price_unit, 2)) if line_price_unit else '0' ET.SubElement(good_service, 'Price').text = str(price_per_unit) ET.SubElement(good_service, 'Qty').text = str(quantity) -- cgit v1.2.3 From 1e3ab6c5d7b34e302d07bdb303982c87aaf59123 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 10 Nov 2025 10:20:58 +0700 Subject: validasi check product bu input --- indoteknik_custom/models/stock_picking.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 0178ac33..eb9d8eda 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1459,6 +1459,9 @@ class StockPicking(models.Model): if len(self.check_product_lines) == 0 and 'BU/PICK/' in self.name: raise UserError(_("Tidak ada Check Product! Harap periksa kembali.")) + if len(self.check_product_lines) == 0 and 'BU/INPUT/' in self.name: + raise UserError(_("Tidak ada Check Product! Harap periksa kembali.")) + if self.total_koli > self.total_so_koli: raise UserError(_("Total Koli (%s) dan Total SO Koli (%s) tidak sama! Harap periksa kembali.") % (self.total_koli, self.t1otal_so_koli)) -- cgit v1.2.3 From c15634a9fba8338c07e3933a893850b8962ce441 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 10 Nov 2025 11:26:49 +0700 Subject: (andri) fix --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index bc33e8e6..37f8b9cc 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2317,7 +2317,7 @@ class SaleOrder(models.Model): raise UserError("Terdapat DUPLIKASI data pada Product {}".format(line.product_id.display_name)) def sale_order_approve(self): - # self.check_duplicate_product() + self.check_duplicate_product() self.check_product_bom() self.check_credit_limit() self.check_limit_so_to_invoice() @@ -2588,7 +2588,7 @@ class SaleOrder(models.Model): for order in self: order._validate_delivery_amt() order._validate_uniform_taxes() - # order.check_duplicate_product() + order.check_duplicate_product() order.check_product_bom() order.check_credit_limit() order.check_limit_so_to_invoice() -- cgit v1.2.3 From 40c863af895ecbcc4af7162c0184f017467bafeb Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 10 Nov 2025 14:56:58 +0700 Subject: (andri) open all jenis biaya realisasi --- indoteknik_custom/models/advance_payment_request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index a3a3d20a..6ea1c160 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -846,9 +846,9 @@ class AdvancePaymentUsageLine(models.Model): attachment_filename_pdf = fields.Char(string='Filename PDF') account_id = fields.Many2one( - 'account.account', string='Jenis Biaya', tracking=3, - domain="[('id', 'in', [484, 486, 488, 506, 507, 625, 471, 519, 527, 528, 529, 530, 565])]" # ID Jenis Biaya yang dibutuhkan + 'account.account', string='Jenis Biaya', tracking=3 # ID Jenis Biaya yang dibutuhkan ) + # domain="[('id', 'in', [484, 486, 488, 506, 507, 625, 471, 519, 527, 528, 529, 530, 565])]" # ID Jenis Biaya yang dibutuhkan is_current_user_ap = fields.Boolean( string="Is Current User AP", -- cgit v1.2.3 From 43fd0cdc3bd0aab6146a29d4400eafbd792057f0 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 10 Nov 2025 15:08:15 +0700 Subject: show desc PO --- indoteknik_custom/models/automatic_purchase.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index ce0328c4..4b0ce325 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -284,7 +284,8 @@ class AutomaticPurchase(models.Model): 'ending_price': line.last_price, 'taxes_id': [(6, 0, [line.taxes_id.id])] if line.taxes_id else False, 'so_line_id': sales_match.sale_line_id.id if sales_match else None, - 'so_id': sales_match.sale_id.id if sales_match else None + 'so_id': sales_match.sale_id.id if sales_match else None, + 'show_description': False if vendor_id == 5571 else True, } new_po_line = self.env['purchase.order.line'].create(param_line) line.current_po_id = new_po.id -- cgit v1.2.3 From 85ff81225eb7f5bf9fd82aee072f75abb15fdf51 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 11 Nov 2025 08:58:30 +0700 Subject: aktivin code ambil uom dari SO --- indoteknik_custom/models/stock_move.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 38cf0199..ff87f911 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -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 4497a43c6a65921902e611f6787341a180cc29f3 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 11 Nov 2025 08:59:07 +0700 Subject: aktivin code ambil uom dari SO --- indoteknik_custom/models/stock_move.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index ff87f911..cac88287 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): -- cgit v1.2.3 From ffe4551ea6eaf0fa97d1a72cbc56596b33825cee Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 11 Nov 2025 11:50:44 +0700 Subject: (andri) add log --- indoteknik_custom/models/sale_order.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 37f8b9cc..357d2395 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2395,6 +2395,7 @@ class SaleOrder(models.Model): self.check_credit_limit() self.check_limit_so_to_invoice() order.approval_status = 'pengajuan1' + order.message_post(body="Mengajukan approval ke Team Sales") return self._create_approval_notification('Team Sales') if not order.with_context(ask_approval=True)._is_request_to_own_team_leader(): @@ -2636,7 +2637,8 @@ class SaleOrder(models.Model): order.approval_status = 'pengajuan1' return self._create_approval_notification('Sales Manager') elif order._requires_approval_team_sales(): - # order.approval_status = 'pengajuan1' + order.approval_status = 'pengajuan1' + order.message_post(body="Mengajukan approval ke Team Sales") return self._create_approval_notification('Team Sales') order.approval_status = 'approved' -- cgit v1.2.3 From f1a8e2740bf42524be6dde351c694edb28786aef Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 11 Nov 2025 14:17:43 +0700 Subject: (andri) fix ask approval --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 357d2395..7070717b 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2759,10 +2759,10 @@ class SaleOrder(models.Model): if user.is_leader or user.is_sales_manager: return True - if self.env.context.get("ask_approval") and user.id in (3401, 20, 3988): + if self.env.context.get("ask_approval") and user.id in (3401, 20, 3988, 17340): return True - if not self.env.context.get("ask_approval") and 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, feby) raise UserError("Yahaha gabisa confirm so, minta ke sales nya ajah") -- cgit v1.2.3 From b74b5bc94ed7a84ca2387fc0373f25b5eb27593d Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 11 Nov 2025 14:43:00 +0700 Subject: (andri) fix usererror --- indoteknik_custom/models/sale_order.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 7070717b..1d34374e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2763,8 +2763,7 @@ class SaleOrder(models.Model): return True if not self.env.context.get("ask_approval") and user.id in (3401, 20, 3988, 17340): # admin (fida, nabila, ninda, feby) - raise UserError("Yahaha gabisa confirm so, minta ke sales nya ajah") - + raise UserError("Sales Admin tidak bisa confirm SO, silahkan hubungi Salesperson yang bersangkutan.") salesperson_id = self.user_id.id approver_id = user.id -- cgit v1.2.3 From c1fec44860dae0d762959f1ab34617f6ef6e42cf Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 11 Nov 2025 15:38:54 +0700 Subject: (andri) fix ask approval for sales admin --- indoteknik_custom/models/sale_order.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 1d34374e..6b1057dd 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2404,6 +2404,13 @@ class SaleOrder(models.Model): 'Hanya bisa konfirmasi SO tim Anda.' ) + user = self.env.user + is_sales_admin = user.id in (3401, 20, 3988, 17340) + if is_sales_admin: + order.approval_status = 'pengajuan1' + order.message_post(body="Mengajukan approval ke Team Sales") + return self._create_approval_notification('Team Sales') + raise UserError("Bisa langsung Confirm") def send_notif_to_salesperson(self, cancel=False): -- cgit v1.2.3 From 704f27afd94787260543a2b6fed2ecfa13e786cb Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 11 Nov 2025 16:01:14 +0700 Subject: fix coretax xml --- indoteknik_custom/models/coretax_fatur.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/coretax_fatur.py b/indoteknik_custom/models/coretax_fatur.py index 7e0de919..cabcd5d6 100644 --- a/indoteknik_custom/models/coretax_fatur.py +++ b/indoteknik_custom/models/coretax_fatur.py @@ -148,8 +148,6 @@ class CoretaxFaktur(models.Model): quantity = line_quantity total_discount = round(line_discount, 2) coretax_id = line.product_uom_id.coretax_id - uom_name = line.product_uom_id.name - # Calculate other tax values otherTaxBase = round(subtotal * (11 / 12), 2) if subtotal else 0 vat_amount = round(otherTaxBase * 0.12, 2) @@ -161,7 +159,7 @@ class CoretaxFaktur(models.Model): ET.SubElement(good_service, 'Opt').text = 'A' ET.SubElement(good_service, 'Code').text = '000000' ET.SubElement(good_service, 'Name').text = line_name - ET.SubElement(good_service, uom_name).text = coretax_id + ET.SubElement(good_service, 'Unit').text = coretax_id # ET.SubElement(good_service, 'Price').text = str(round(line_price_unit, 2)) if line_price_unit else '0' ET.SubElement(good_service, 'Price').text = str(price_per_unit) ET.SubElement(good_service, 'Qty').text = str(quantity) -- cgit v1.2.3 From 4274751a04b7fc02b38a0af4683f06ae4f5508ad Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 12 Nov 2025 08:41:10 +0700 Subject: fix notify --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 6b1057dd..861089d5 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2395,8 +2395,8 @@ class SaleOrder(models.Model): self.check_credit_limit() self.check_limit_so_to_invoice() order.approval_status = 'pengajuan1' - order.message_post(body="Mengajukan approval ke Team Sales") - return self._create_approval_notification('Team Sales') + order.message_post(body="Mengajukan approval ke Sales") + return self._create_approval_notification('Sales') if not order.with_context(ask_approval=True)._is_request_to_own_team_leader(): return self._create_notification_action( -- cgit v1.2.3 From 1086aadae846f8334cdb0292c606fb5a4d186f89 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 12 Nov 2025 08:42:34 +0700 Subject: fix --- indoteknik_custom/models/sale_order.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 861089d5..2de4109d 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2395,8 +2395,8 @@ class SaleOrder(models.Model): self.check_credit_limit() self.check_limit_so_to_invoice() order.approval_status = 'pengajuan1' - order.message_post(body="Mengajukan approval ke Sales") - return self._create_approval_notification('Sales') + order.message_post(body="Mengajukan approval ke Team Sales") + return self._create_approval_notification('Team Sales') if not order.with_context(ask_approval=True)._is_request_to_own_team_leader(): return self._create_notification_action( @@ -2408,8 +2408,8 @@ class SaleOrder(models.Model): is_sales_admin = user.id in (3401, 20, 3988, 17340) if is_sales_admin: order.approval_status = 'pengajuan1' - order.message_post(body="Mengajukan approval ke Team Sales") - return self._create_approval_notification('Team Sales') + order.message_post(body="Mengajukan approval ke Sales") + return self._create_approval_notification('Sales') raise UserError("Bisa langsung Confirm") -- cgit v1.2.3 From 583a8e3064790a06063d5dc1b06ed8122bb22e4e Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 12 Nov 2025 08:44:27 +0700 Subject: (andri) fix --- indoteknik_custom/models/sale_order.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 2de4109d..8e731307 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2383,12 +2383,14 @@ class SaleOrder(models.Model): if order._requires_approval_margin_leader(): order.approval_status = 'pengajuan2' + order.message_post(body="Mengajukan approval ke Pimpinan") return self._create_approval_notification('Pimpinan') elif order._requires_approval_margin_manager(): self.check_product_bom() self.check_credit_limit() self.check_limit_so_to_invoice() order.approval_status = 'pengajuan1' + order.message_post(body="Mengajukan approval ke Sales Manager") return self._create_approval_notification('Sales Manager') elif order._requires_approval_team_sales(): self.check_product_bom() -- cgit v1.2.3 From 7049765e3fa5ffca23725d652134ab3662912762 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 12 Nov 2025 23:57:23 +0700 Subject: add tracking so fiktif --- indoteknik_custom/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 8e731307..14b66d87 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -398,7 +398,7 @@ class SaleOrder(models.Model): compute="_compute_partner_is_cbd_locked" ) internal_notes_contact = fields.Text(related='partner_id.comment', string="Internal Notes", readonly=True, help="Internal Notes dari contact utama customer.") - is_so_fiktif = fields.Boolean('SO Fiktif?') + is_so_fiktif = fields.Boolean('SO Fiktif?', tracking=3) def action_set_shipping_id(self): for rec in self: -- cgit v1.2.3 From e1c3a9b0ab65a698eeb64b7ab17dd82558c273fa Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 12 Nov 2025 23:58:03 +0700 Subject: add tracking so fiktif --- indoteknik_custom/models/stock_picking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 49001974..7c4cea8b 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -200,7 +200,7 @@ class StockPicking(models.Model): ('full', 'Full'), ], string='Delivery Status', compute='_compute_delivery_status_detail', store=False) so_num = fields.Char('SO Number', compute='_get_so_num') - is_so_fiktif = fields.Boolean('SO Fiktif?', compute='_compute_is_so_fiktif') + is_so_fiktif = fields.Boolean('SO Fiktif?', compute='_compute_is_so_fiktif', tracking=3) @api.depends('sale_id.is_so_fiktif') def _compute_is_so_fiktif(self): -- cgit v1.2.3 From 39c95b7097f188350d71414c72f6abe7a711cf18 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 13 Nov 2025 15:12:09 +0700 Subject: (andri) fix sync janji bayar --- indoteknik_custom/models/account_move.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 684ef335..c460a332 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -161,7 +161,8 @@ class AccountMove(models.Model): def action_sync_promise_date(self): self.ensure_one() finance_user_ids = [688] - if self.env.user.id not in finance_user_ids: + is_it = self.env.user.has_group('indoteknik_custom.group_role_it') + if self.env.user.id not in finance_user_ids and not is_it: raise UserError('Hanya Finance (Widya) yang dapat menggunakan fitur ini.') if not self.customer_promise_date: raise UserError("Isi Janji Bayar terlebih dahulu sebelum melakukan sinkronisasi.") @@ -169,10 +170,11 @@ class AccountMove(models.Model): other_invoices = self.env['account.move'].search([ ('id', '!=', self.id), ('partner_id', '=', self.partner_id.id), - ('invoice_date_due', '=', self.invoice_date_due), + ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), ('move_type', '=', 'out_invoice'), ('state', '=', 'posted'), - ('date_terima_tukar_faktur', '!=', False) + ('date_terima_tukar_faktur', '!=', False), + ('invoice_payment_term_id.name', 'ilike', 'tempo') ]) lines = [] for inv in other_invoices: -- cgit v1.2.3 From 37469d36fe1d03f3c497e8aba34bc6d81fff033f Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 13 Nov 2025 16:29:35 +0700 Subject: checkpoint calculate commission internal using helper --- indoteknik_custom/models/commission_internal.py | 233 ++++++++++++++++++++++++ 1 file changed, 233 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py index 8a333bda..ce074bcc 100644 --- a/indoteknik_custom/models/commission_internal.py +++ b/indoteknik_custom/models/commission_internal.py @@ -26,6 +26,8 @@ class CommissionInternal(models.Model): comment = fields.Char(string='Comment') commission_internal_line = fields.One2many('commission.internal.line', 'commission_internal_id', string='Lines', auto_join=True, order='account_move_id asc') + commission_internal_result = fields.One2many('commission.internal.result', 'commission_internal_id', string='Result', + auto_join=True, order='account_move_id asc') @api.model def create(self, vals): @@ -67,6 +69,194 @@ class CommissionInternal(models.Model): return dt_start, dt_end + # CREDIT > 0 + def _calculate_exclude_credit(self): + query = [ + ('commission_internal_id.id', '=', self.id), + ('credit', '>', 0), + ('status', '=', False) + ] + lines = self.env['commission.internal.line'].search(query) + for line in lines: + line.helper1 = 'CREDIT' + + # INV/20 + def _calculate_keyword_invoice(self): + query = [ + ('commission_internal_id.id', '=', self.id), + ('helper1', '=', False), + ('label', 'ilike', '%INV/20%'), + ] + lines = self.env['commission.internal.line'].search(query) + # parse label and set helper + for line in lines: + line.helper1 = 'INV/20' + + # ONGKOS KIRIM SO/20 + def _calculate_keyword_deliveryamt(self): + query = [ + ('commission_internal_id.id', '=', self.id), + ('helper1', '=', False), + ('label', 'ilike', '%ONGKOS KIRIM SO/20%'), + ] + lines = self.env['commission.internal.line'].search(query) + for line in lines: + line.helper1 = 'ONGKOS KIRIM SO/20' + + # Payment SO/20 + def _calculate_keyword_payment(self): + query = [ + ('commission_internal_id.id', '=', self.id), + ('helper1', '=', False), + ('label', 'ilike', '%Payment SO/20%'), + ] + lines = self.env['commission.internal.line'].search(query) + for line in lines: + line.helper1 = 'Payment SO/20' + + # UANG MUKA PENJUALAN SO/20 + def _calculate_keyword_dp(self): + query = [ + ('commission_internal_id.id', '=', self.id), + ('helper1', '=', False), + ('label', 'ilike', '%UANG MUKA PENJUALAN SO/20%'), + ] + lines = self.env['commission.internal.line'].search(query) + for line in lines: + line.helper1 = 'UANG MUKA PENJUALAN SO/20' + + def _calculate_keyword_undefined(self): + query = [ + ('commission_internal_id.id', '=', self.id), + ('helper1', '=', False), + ] + lines = self.env['commission.internal.line'].search(query) + for line in lines: + line.helper1 = 'UNDEFINED' + + def _parse_label_helper2(self): + exception = ['CREDIT', 'UNDEFINED'] + query = [ + ('commission_internal_id.id', '=', self.id), + ('helper1', 'not in', exception) + ] + lines = self.env['commission.internal.line'].search(query) + for line in lines: + clean_label = line.label.replace('-', ' ').replace(',', ' ') + list_label = clean_label.split() + list_helper2 = [] + for key in list_label: + clean_key = key.replace(',', '') # delete commas for make sure + if clean_key[:6] == 'INV/20': + list_helper2.append(clean_key) + elif clean_key[:5] == 'SO/20': + list_invoice = self._switch_so_to_inv(clean_key) + str_invoice = ' '.join(list_invoice) + list_helper2.append(str_invoice) + result_helper2 = ' '.join(list_helper2) + line.helper2 = result_helper2 + + def _switch_so_to_inv(self, order): + list_state = ['sale', 'done'] + result = [] + query = [ + ('state', 'in', list_state), + ('name', '=', order) + ] + sales = self.env['sale.order'].search(query) + if sales: + for sale in sales: + if sale.invoice_ids: + for invoice in sale.invoice_ids: + if invoice.state == 'posted': + result.append(invoice.name) + else: + result.append(order) + else: + result.append(order) + return result + + # fill later TODO @stephan + def calculate_commission_internal_result(self): + query = [ + ('commission_internal_id.id', '=', self.id), + ('helper2', '!=', False) + ] + lines = self.env['commission.internal.line'].search(query) + for line in lines: + list_so = list_invoice = [] + list_key = line.helper2.split() + for key in list_key: + if key[:6] == 'INV/20': + list_invoice.append(key) + if key[:5] == 'SO/20': + list_so.append(key) + invoices = self.env['account.move'].search([('state', '=', 'posted'), ('name', 'in', list_invoice)]) + orders = self.env['sale.order'].search([('state', 'in', ['done', 'sale']), ('name', 'in', list_so)]) + invoice_data = invoices.mapped(lambda r: { + 'res_name': 'account.move', + 'res_id': r.id, + 'name': r.name, + 'date': r.invoice_date, + 'customer': r.partner_id.name, + 'salesperson': r.user_id.name, + 'amount_untaxed': r.amount_untaxed, + 'amount_tax': r.amount_tax, + 'amount_total': r.amount_total + }) + sale_data = orders.mapped(lambda r: { + 'res_name': 'sale.order', + 'res_id': r.id, + 'name': r.name, + 'date': r.date_order, + 'customer': r.partner_id.name, + 'salesperson': r.user_id.name, + 'amount_untaxed': r.amount_untaxed, + 'amount_tax': r.amount_tax, + 'amount_total': r.grand_total + }) + invoices_and_sales = invoice_data + sale_data + total_amount = sum(item.get('amount_total', 0.0) for item in invoices_and_sales) + for data in invoices_and_sales: + prorate = data.get('amount_total', 0.0) / total_amount + # net_amount_prorate = data.get('amount_total', 0.0) * prorate + net_amount_prorate = line.balance * prorate + self.env['commission.internal.result'].create([{ + 'commission_internal_id': line.commission_internal_id.id, + 'commission_internal_line_id': line.id, + 'date_doc': data['date'], + 'number': data['name'], + 'res_name': data['res_name'], + 'res_id': data['res_id'], + 'name': data['name'], + 'salesperson': data['salesperson'], + 'totalamt': data['amount_total'], + 'uang_masuk_line_id': line.account_move_line_id.id, + 'uang_masuk_id': line.account_move_id.id, + 'date_uang_masuk': line.date, + 'label_uang_masuk': line.label, + 'nomor_uang_masuk': line.number, + 'uang_masuk': line.balance, + 'linenetamt_prorate': net_amount_prorate, + 'helper1': line.helper1 + }]) + print(1) + print(1) + + # this button / method works for train data in July 2025 + def calculate_commission_internal_from_keyword(self): + if not self.commission_internal_line: + raise UserError('Commission Internal Line kosong, click Copy GL terlebih dahulu') + # execute helper1 for mark keyword + self._calculate_exclude_credit() + self._calculate_keyword_invoice() + self._calculate_keyword_deliveryamt() + self._calculate_keyword_payment() + self._calculate_keyword_dp() + self._calculate_keyword_undefined() + # execute helper2 for parse the label into INV/ or SO/ and switch SO to INV if available + self._parse_label_helper2() + def generate_commission_from_generate_ledger(self): if self.commission_internal_line: raise UserError('Harus hapus semua line jika ingin generate ulang') @@ -127,3 +317,46 @@ class CommissionInternalLine(models.Model): linenetamt = fields.Float(string='Net Amount') dpp = fields.Float(string='DPP') status = fields.Char(string='Status') + salespersons = fields.Char(string='Salespersons') + invoices = fields.Char(string='Invoices') + helper1 = fields.Char(string='Helper1') + helper2 = fields.Char(string='Helper2') + helper3 = fields.Char(string='Helper3') + helper4 = fields.Char(string='Helper4') + helper5 = fields.Char(string='Helper5') + + +class CommissionInternalResult(models.Model): + _name = 'commission.internal.result' + _description = 'Result' + _order = 'number asc, id' + + commission_internal_id = fields.Many2one('commission.internal', string='Internal Ref', required=True, + ondelete='cascade', index=True, copy=False) + commission_internal_line_id = fields.Many2one('commission.internal.line', string='Line Ref') + res_name = fields.Char(string='Res Name') + res_id = fields.Integer(string='Res ID') + date_doc = fields.Date(string='Date Doc') + number = fields.Char(string='Number') + name = fields.Char(string='Name') + salesperson = fields.Char(string='Salesperson') + totalamt = fields.Float(string='Total Amount') + uang_masuk_line_id = fields.Many2one('account.move.line', string='Uang Masuk Line ID') + uang_masuk_id = fields.Many2one('account.move', string='Uang Masuk ID') + date_uang_masuk = fields.Date(string='Date Uang Masuk') + label_uang_masuk = fields.Char(string='Label Uang Masuk') + nomor_uang_masuk = fields.Char(string='Nomor Uang Masuk') + uang_masuk = fields.Float(string='Uang Masuk') + ongkir = fields.Float(string='Ongkir') + refund = fields.Float(string='Refund') + pph = fields.Float(string='PPh23') + others = fields.Float(string='Others') + linenetamt = fields.Float(string='Net Amount') + linenetamt_prorate = fields.Float(string='Net Amount Prorate') + dpp = fields.Float(string='DPP') + status = fields.Char(string='Status') + helper1 = fields.Char(string='Helper1') + helper2 = fields.Char(string='Helper2') + helper3 = fields.Char(string='Helper3') + helper4 = fields.Char(string='Helper4') + helper5 = fields.Char(string='Helper5') -- cgit v1.2.3 From ae89c43f6efa66ac7e332e62ce6cc6817f75c16d Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 13 Nov 2025 17:06:48 +0700 Subject: (andri) add invoice payment widget di tree inv, unlock COA reimburse, and add tracking edit pricelist contact --- indoteknik_custom/models/account_move.py | 27 +++++++++++++++++++++- .../models/advance_payment_request.py | 3 +-- indoteknik_custom/models/res_partner.py | 3 +++ 3 files changed, 30 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index c460a332..12e8ecba 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -3,7 +3,7 @@ from odoo.exceptions import AccessError, UserError, ValidationError from markupsafe import escape as html_escape from datetime import timedelta, date, datetime from pytz import timezone, utc -import logging +import logging, json import base64 import PyPDF2 import os @@ -108,6 +108,31 @@ class AccountMove(models.Model): ) internal_notes_contact = fields.Text(related='partner_id.comment', string="Internal Notes", readonly=True, help="Internal Notes dari contact utama customer.") + payment_info = fields.Text( + string="Payment Info", + compute='_compute_payment_info', + store=False, + help="Informasi pembayaran yang diambil dari payment yang sudah direkonsiliasi ke invoice ini." + ) + + def _compute_payment_info(self): + for rec in self: + summary = "" + try: + widget_data = rec.invoice_payments_widget + if widget_data: + data = json.loads(widget_data) + lines = [] + for item in data.get('content', []): + amount = item.get('amount', 0.0) + date = item.get('date') or item.get('payment_date') or '' + formatted_amount = formatLang(self.env, amount, currency_obj=rec.currency_id) + lines.append(f"Paid on {date} - {formatted_amount}") + summary = "\n".join(lines) if lines else (data.get('title', '') or "") + except Exception: + summary = "" + rec.payment_info = summary + # def _check_and_lock_cbd(self): # cbd_term = self.env['account.payment.term'].browse(26) # today = date.today() diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index 6ea1c160..42097923 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -909,8 +909,7 @@ class ReimburseLine(models.Model): date = fields.Date(string='Tanggal', required=True, default=fields.Date.today) account_id = fields.Many2one( 'account.account', - string='Jenis Biaya', tracking=3, - domain="[('id', 'in', [484, 486, 527, 529, 530, 471, 473, 492, 493, 488, 625, 528, 533, 534])]" + string='Jenis Biaya', tracking=3 ) description = fields.Text(string='Description', required=True, tracking=3) distance_departure = fields.Float(string='Pergi (Km)', tracking=3) diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index f80bbcb6..7f4feb75 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -200,6 +200,9 @@ class ResPartner(models.Model): string='Previous Payment Term' ) + property_product_pricelist = fields.Many2one( + tracking=True + ) @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id", "kecamatan_id") -- cgit v1.2.3 From 83ceea85773615bf3f031554fa2ef9a2bc7c7760 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Fri, 14 Nov 2025 14:01:33 +0700 Subject: (andri) fix printout penutupan tempo --- indoteknik_custom/models/account_move.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 12e8ecba..5e38b544 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -32,7 +32,6 @@ class AccountMove(models.Model): new_due_date = fields.Date(string='New Due') counter = fields.Integer(string="Counter", default=0) cost_centre_id = fields.Many2one('cost.centre', string='Cost Centre') - analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account') due_line = fields.One2many('due.extension.line', 'invoice_id', compute='_compute_due_line', string='Due Extension Lines') no_faktur_pajak = fields.Char(string='No Faktur Pajak') date_completed = fields.Datetime(string='Date Completed') @@ -127,8 +126,8 @@ class AccountMove(models.Model): amount = item.get('amount', 0.0) date = item.get('date') or item.get('payment_date') or '' formatted_amount = formatLang(self.env, amount, currency_obj=rec.currency_id) - lines.append(f"Paid on {date} - {formatted_amount}") - summary = "\n".join(lines) if lines else (data.get('title', '') or "") + lines.append(f"
  • Paid on {date} - {formatted_amount}
  • ") + summary = f"
      {''.join(lines)}
    " if lines else (data.get('title', '') or "") except Exception: summary = "" rec.payment_info = summary -- cgit v1.2.3 From 6fe8ab222556bf623ee916e0d92cd5557e9b04d5 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 14 Nov 2025 14:39:40 +0700 Subject: testing commission internal --- indoteknik_custom/models/commission_internal.py | 84 ++++++++++++++++--------- 1 file changed, 56 insertions(+), 28 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py index ce074bcc..bc668c28 100644 --- a/indoteknik_custom/models/commission_internal.py +++ b/indoteknik_custom/models/commission_internal.py @@ -2,6 +2,7 @@ from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date import logging +import pandas as pd _logger = logging.getLogger(__name__) @@ -178,11 +179,14 @@ class CommissionInternal(models.Model): # fill later TODO @stephan def calculate_commission_internal_result(self): + exception = ['ONGKOS KIRIM SO/20'] query = [ ('commission_internal_id.id', '=', self.id), - ('helper2', '!=', False) + ('helper2', '!=', False), + ('helper1', 'not in', exception) ] lines = self.env['commission.internal.line'].search(query) + all_invoices_and_sales = [] for line in lines: list_so = list_invoice = [] list_key = line.helper2.split() @@ -202,7 +206,17 @@ class CommissionInternal(models.Model): 'salesperson': r.user_id.name, 'amount_untaxed': r.amount_untaxed, 'amount_tax': r.amount_tax, - 'amount_total': r.amount_total + 'amount_total': r.amount_total, + 'uang_masuk_line_id': line.account_move_line_id.id, + 'uang_masuk_id': line.account_move_id.id, + 'date_uang_masuk': line.date, + 'label_uang_masuk': line.label, + 'nomor_uang_masuk': line.number, + 'uang_masuk': line.balance, + # 'linenetamt_prorate': net_amount_prorate, + 'helper1': line.helper1, + 'commission_internal_id': line.commission_internal_id.id, + 'commission_internal_line_id': line.id, }) sale_data = orders.mapped(lambda r: { 'res_name': 'sale.order', @@ -213,34 +227,48 @@ class CommissionInternal(models.Model): 'salesperson': r.user_id.name, 'amount_untaxed': r.amount_untaxed, 'amount_tax': r.amount_tax, - 'amount_total': r.grand_total + 'amount_total': r.grand_total, + 'uang_masuk_line_id': line.account_move_line_id.id, + 'uang_masuk_id': line.account_move_id.id, + 'date_uang_masuk': line.date, + 'label_uang_masuk': line.label, + 'nomor_uang_masuk': line.number, + 'uang_masuk': line.balance, + # 'linenetamt_prorate': net_amount_prorate, + 'helper1': line.helper1, + 'commission_internal_id': line.commission_internal_id.id, + 'commission_internal_line_id': line.id, }) invoices_and_sales = invoice_data + sale_data - total_amount = sum(item.get('amount_total', 0.0) for item in invoices_and_sales) - for data in invoices_and_sales: - prorate = data.get('amount_total', 0.0) / total_amount - # net_amount_prorate = data.get('amount_total', 0.0) * prorate - net_amount_prorate = line.balance * prorate - self.env['commission.internal.result'].create([{ - 'commission_internal_id': line.commission_internal_id.id, - 'commission_internal_line_id': line.id, - 'date_doc': data['date'], - 'number': data['name'], - 'res_name': data['res_name'], - 'res_id': data['res_id'], - 'name': data['name'], - 'salesperson': data['salesperson'], - 'totalamt': data['amount_total'], - 'uang_masuk_line_id': line.account_move_line_id.id, - 'uang_masuk_id': line.account_move_id.id, - 'date_uang_masuk': line.date, - 'label_uang_masuk': line.label, - 'nomor_uang_masuk': line.number, - 'uang_masuk': line.balance, - 'linenetamt_prorate': net_amount_prorate, - 'helper1': line.helper1 - }]) - print(1) + sum_amount_total = sum(item['amount_total'] for item in invoices_and_sales) + for item in invoices_and_sales: + item['sum_amount_total'] = sum_amount_total + all_invoices_and_sales.extend(invoices_and_sales) + + for data in all_invoices_and_sales: + # total_amount = sum(item.get('amount_total', 0.0) for item in invoices_and_sales) + # net_amount_prorate = data.get('amount_total', 0.0) * prorate + prorate = data.get('amount_total', 0.0) / data.get('sum_amount_total', 0.0) + net_amount_prorate = data.get('uang_masuk', 0.0) * prorate + self.env['commission.internal.result'].create([{ + 'commission_internal_id': data['commission_internal_id'], + 'commission_internal_line_id': data['commission_internal_line_id'], + 'date_doc': data['date'], + 'number': data['name'], + 'res_name': data['res_name'], + 'res_id': data['res_id'], + 'name': data['name'], + 'salesperson': data['salesperson'], + 'totalamt': data['amount_total'], + 'uang_masuk_line_id': data['uang_masuk_line_id'], + 'uang_masuk_id': data['uang_masuk_id'], + 'date_uang_masuk': data['date_uang_masuk'], + 'label_uang_masuk': data['label_uang_masuk'], + 'nomor_uang_masuk': data['nomor_uang_masuk'], + 'uang_masuk': data['uang_masuk'], + 'linenetamt_prorate': net_amount_prorate, + 'helper1': data['helper1'] + }]) print(1) # this button / method works for train data in July 2025 -- cgit v1.2.3 From 5322376db0faea9de44243f2d747e68eb1713d75 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 14 Nov 2025 14:49:48 +0700 Subject: remove pandas --- indoteknik_custom/models/commission_internal.py | 1 - 1 file changed, 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py index bc668c28..66d32706 100644 --- a/indoteknik_custom/models/commission_internal.py +++ b/indoteknik_custom/models/commission_internal.py @@ -2,7 +2,6 @@ from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date import logging -import pandas as pd _logger = logging.getLogger(__name__) -- cgit v1.2.3 From 93f431a8d96bb46cb34ad9629d450b34a531265c Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 14 Nov 2025 15:22:48 +0700 Subject: fix ccm X --- indoteknik_custom/models/tukar_guling.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py index 99a74505..c8375161 100644 --- a/indoteknik_custom/models/tukar_guling.py +++ b/indoteknik_custom/models/tukar_guling.py @@ -737,14 +737,12 @@ class TukarGuling(models.Model): if mapping_koli and record.operations.picking_type_id.id == 29: for prod in mapping_koli.mapped('product_id'): 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"Move BU/OUT tidak ditemukan untuk produk {prod.display_name}") - srt_return_lines.append((0, 0, { - 'product_id': prod.id, - 'quantity': qty_total, - 'move_id': move.id, - })) + for ml in bu_out.move_line_ids.filtered(lambda ml: ml.qty_done > 0 and not ml.package_id): + srt_return_lines.append((0, 0, { + 'product_id': ml.product_id.id, + 'quantity': ml.qty_done, + 'move_id': ml.move_id.id, + })) _logger.info(f"📟 SRT line: {prod.display_name} | qty={qty_total}") elif not mapping_koli and record.operations.picking_type_id.id == 29: -- cgit v1.2.3 From f1bf6c4cfa31446a15e5678a80c023cadba64f86 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 14 Nov 2025 16:19:19 +0700 Subject: fix ccm --- indoteknik_custom/models/tukar_guling.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py index c8375161..aa116ce3 100644 --- a/indoteknik_custom/models/tukar_guling.py +++ b/indoteknik_custom/models/tukar_guling.py @@ -737,12 +737,18 @@ class TukarGuling(models.Model): if mapping_koli and record.operations.picking_type_id.id == 29: for prod in mapping_koli.mapped('product_id'): qty_total = sum(mk.qty_return for mk in mapping_koli.filtered(lambda m: m.product_id == prod)) - for ml in bu_out.move_line_ids.filtered(lambda ml: ml.qty_done > 0 and not ml.package_id): + + move_lines = bu_out.move_line_ids.filtered( + lambda ml: ml.product_id == prod and ml.qty_done > 0 and not ml.package_id + ) + + for ml in move_lines: srt_return_lines.append((0, 0, { 'product_id': ml.product_id.id, 'quantity': ml.qty_done, 'move_id': ml.move_id.id, })) + _logger.info(f"📟 SRT line: {prod.display_name} | qty={qty_total}") elif not mapping_koli and record.operations.picking_type_id.id == 29: -- cgit v1.2.3 From 6b253ed4dc5346ee8f5cefed035ab8a2d02e90ac Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 14 Nov 2025 17:01:38 +0700 Subject: BD iu approval fix --- indoteknik_custom/models/stock_picking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 7c4cea8b..f69e5fa9 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1603,7 +1603,7 @@ class StockPicking(models.Model): self.tukar_guling_po_id.update_doc_state() user = self.env.user - if not user.has_group('indoteknik_custom.group_role_logistic'): + if not user.has_group('indoteknik_custom.group_role_logistic') and 'BU/IU' in self.name: raise UserWarning('Validate hnaya bisa di lakukan oleh logistik') return res -- cgit v1.2.3 From db87e7d19b369b7f0181f9ffc774cce5adc76091 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 17 Nov 2025 10:37:04 +0700 Subject: push --- indoteknik_custom/models/refund_sale_order.py | 40 ++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 9eae5b32..bbab3ec4 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -326,8 +326,23 @@ class RefundSaleOrder(models.Model): domain.append(('ref', 'ilike', n)) moves2 = self.env['account.move'].search(domain) + moves3 = self.env['account.move'] + if so_ids: + so_names = self.env['sale.order'].browse(so_ids).mapped('name') + domain = [ + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ('ref', 'ilike', 'uang muka penjualan') + ] + if so_names: + domain += ['|'] * (len(so_names) - 1) + for n in so_names: + domain.append(('ref', 'ilike', n)) + moves3 = self.env['account.move'].search(domain) + has_moves = bool(moves) has_moves2 = bool(moves2) + has_moves3 = bool(moves3) has_piutangmdr = bool(piutangmdr) has_piutangbca = bool(piutangbca) has_misc = bool(misc) @@ -349,6 +364,8 @@ class RefundSaleOrder(models.Model): # sisanya bisa dijumlahkan tanpa konflik if has_moves2: amounts.append(sum(moves2.mapped('amount_total_signed'))) + if has_moves3: + amounts.append(sum(moves3.mapped('amount_total_signed'))) if has_piutangbca: amounts.append(sum(piutangbca.mapped('amount_total_signed'))) if has_piutangmdr: @@ -573,9 +590,10 @@ class RefundSaleOrder(models.Model): domain = [ ('journal_id', '=', 11), ('state', '=', 'posted'), - '|', + '|', '|', ('ref', 'ilike', 'dp'), ('ref', 'ilike', 'payment'), + ('ref', 'ilike', 'uang muka penjualan'), ] domain += ['|'] * (len(so_names) - 1) for n in so_names: @@ -653,6 +671,7 @@ class RefundSaleOrder(models.Model): ('journal_id', '=', 13), ('state', '=', 'posted'), ]) + moves2 = self.env['account.move'] if so_ids: so_records = self.env['sale.order'].browse(so_ids) @@ -668,9 +687,26 @@ class RefundSaleOrder(models.Model): domain.append(('ref', 'ilike', n)) moves2 = self.env['account.move'].search(domain) + + moves3 = self.env['account.move'] + if so_ids: + so_records = self.env['sale.order'].browse(so_ids) + so_names = so_records.mapped('name') + + domain = [ + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ('ref', 'ilike', 'uang muka penjualan') + ] + domain += ['|'] * (len(so_names) - 1) + for n in so_names: + domain.append(('ref', 'ilike', n)) + + moves3 = self.env['account.move'].search(domain) has_moves = bool(moves) has_moves2 = bool(moves2) + has_moves3 = bool(moves3) has_piutangmdr = bool(piutangmdr) has_piutangbca = bool(piutangbca) has_misc = bool(misc) @@ -685,6 +721,8 @@ class RefundSaleOrder(models.Model): amounts.append(sum(moves.mapped('amount_total_signed'))) if has_moves2: amounts.append(sum(moves2.mapped('amount_total_signed'))) + if has_moves3: + amounts.append(sum(moves3.mapped('amount_total_signed'))) if has_piutangbca: amounts.append(sum(piutangbca.mapped('amount_total_signed'))) if has_piutangmdr: -- cgit v1.2.3 From bdaad593bd6b3853f98cfc8d203c49474bbb69ac Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 17 Nov 2025 10:49:48 +0700 Subject: push --- indoteknik_custom/models/refund_sale_order.py | 66 +++++++++++++-------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index bbab3ec4..c6db2174 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -750,39 +750,39 @@ class RefundSaleOrder(models.Model): if self.sale_order_ids: self.partner_id = self.sale_order_ids[0].partner_id - @api.constrains('sale_order_ids') - def _check_sale_orders_payment(self): - """ Validasi SO harus punya uang masuk (Journal Uang Muka / Midtrans) """ - for rec in self: - invalid_orders = [] - - for so in rec.sale_order_ids: - # cari journal uang muka - moves = self.env['account.move'].search([ - ('sale_id', '=', so.id), - ('journal_id', '=', 11), # Journal Uang Muka - ('state', '=', 'posted'), - ]) - piutangbca = self.env['account.move'].search([ - ('ref', 'in', rec.invoice_ids.mapped('name')), - ('journal_id', '=', 4), - ('state', '=', 'posted'), - ]) - piutangmdr = self.env['account.move'].search([ - ('ref', 'in', rec.invoice_ids.mapped('name')), - ('journal_id', '=', 7), - ('state', '=', 'posted'), - ]) - - if not moves and so.payment_status != 'settlement' and not piutangbca and not piutangmdr: - invalid_orders.append(so.name) - - if invalid_orders: - raise ValidationError( - f"Tidak dapat membuat refund untuk SO {', '.join(invalid_orders)} " - "karena tidak memiliki Record Uang Masuk (Journal Uang Muka/Payment Invoice/Midtrans).\n" - "Pastikan semua SO yang dipilih sudah memiliki Record pembayaran yang valid." - ) + # @api.constrains('sale_order_ids') + # def _check_sale_orders_payment(self): + # """ Validasi SO harus punya uang masuk (Journal Uang Muka / Midtrans) """ + # for rec in self: + # invalid_orders = [] + + # for so in rec.sale_order_ids: + # # cari journal uang muka + # moves = self.env['account.move'].search([ + # ('sale_id', '=', so.id), + # ('journal_id', '=', 11), # Journal Uang Muka + # ('state', '=', 'posted'), + # ]) + # piutangbca = self.env['account.move'].search([ + # ('ref', 'in', rec.invoice_ids.mapped('name')), + # ('journal_id', '=', 4), + # ('state', '=', 'posted'), + # ]) + # piutangmdr = self.env['account.move'].search([ + # ('ref', 'in', rec.invoice_ids.mapped('name')), + # ('journal_id', '=', 7), + # ('state', '=', 'posted'), + # ]) + + # if not moves and so.payment_status != 'settlement' and not piutangbca and not piutangmdr: + # invalid_orders.append(so.name) + + # if invalid_orders: + # raise ValidationError( + # f"Tidak dapat membuat refund untuk SO {', '.join(invalid_orders)} " + # "karena tidak memiliki Record Uang Masuk (Journal Uang Muka/Payment Invoice/Midtrans).\n" + # "Pastikan semua SO yang dipilih sudah memiliki Record pembayaran yang valid." + # ) @api.onchange('refund_type') def _onchange_refund_type(self): -- cgit v1.2.3 From 6f254e896a0a788ac7f3a8c1668be5f31f70b640 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 17 Nov 2025 12:02:35 +0700 Subject: (andri) add field infomation line pada dunning run + fix approve due extension log --- indoteknik_custom/models/account_move_due_extension.py | 5 +++++ indoteknik_custom/models/dunning_run.py | 1 + 2 files changed, 6 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move_due_extension.py b/indoteknik_custom/models/account_move_due_extension.py index 55fc6c65..951d9745 100644 --- a/indoteknik_custom/models/account_move_due_extension.py +++ b/indoteknik_custom/models/account_move_due_extension.py @@ -115,6 +115,11 @@ class DueExtension(models.Model): self.order_id.check_credit_limit() self.order_id.approval_status = 'pengajuan1' return self.order_id._create_approval_notification('Sales Manager') + + if self.order_id._requires_approval_team_sales(): + self.order_id.check_credit_limit() + self.order_id.approval_status = 'pengajuan1' + return self.order_id._create_approval_notification('Team Sales') sales = self.env['sale.order'].browse(self.order_id.id) diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index 9feea1d1..2562c305 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -150,4 +150,5 @@ class DunningRunLine(models.Model): open_amt = fields.Float(string='Open Amount') due_date = fields.Date(string='Due Date') payment_term = fields.Many2one('account.payment.term', related='invoice_id.invoice_payment_term_id', string='Payment Term') + information_line = fields.Text(string='Information') -- cgit v1.2.3 From 0e026757427842dc865a5cbf17f2e3d85a30875c Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 17 Nov 2025 17:10:38 +0700 Subject: prevent schedule action --- indoteknik_custom/models/account_move.py | 16 ++++++++++++++++ indoteknik_custom/models/purchase_order.py | 10 ++++++++++ indoteknik_custom/models/sj_tele.py | 10 ++++++++++ 3 files changed, 36 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 5e38b544..6212664e 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -11,6 +11,7 @@ import re from terbilang import Terbilang from collections import defaultdict from odoo.tools.misc import formatLang +import socket _logger = logging.getLogger(__name__) @@ -218,7 +219,16 @@ class AccountMove(models.Model): 'target': 'new', } + @staticmethod + def is_local_env(): + hostname = socket.gethostname().lower() + keywords = ['andri', 'miqdad', 'fin', 'stephan', 'hafid', 'nathan'] + return any(keyword in hostname for keyword in keywords) + def send_due_invoice_reminder(self): + if self.is_local_env(): + _logger.warning("📪 Local environment detected — skip sending email reminders.") + return today = fields.Date.today() target_dates = [ today + timedelta(days=7), @@ -240,6 +250,9 @@ class AccountMove(models.Model): self._send_invoice_reminders(invoices, mode='due') def send_overdue_invoice_reminder(self): + if self.is_local_env(): + _logger.warning("📪 Local environment detected — skip sending email reminders.") + return today = fields.Date.today() invoices = self.env['account.move'].search([ ('move_type', '=', 'out_invoice'), @@ -255,6 +268,9 @@ class AccountMove(models.Model): self._send_invoice_reminders(invoices, mode='overdue') def _send_invoice_reminders(self, invoices, mode): + if self.is_local_env(): + _logger.warning("📪 Local environment detected — skip sending email reminders.") + return today = fields.Date.today() template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 4475e777..3312e7fd 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -7,6 +7,8 @@ from pytz import timezone, utc import io import base64 from odoo.tools import lazy_property +import socket + try: from odoo.tools.misc import xlsxwriter except ImportError: @@ -121,6 +123,11 @@ class PurchaseOrder(models.Model): default=True ) + @staticmethod + def is_local_env(): + hostname = socket.gethostname().lower() + keywords = ['andri', 'miqdad', 'fin', 'stephan', 'hafid', 'nathan'] + return any(keyword in hostname for keyword in keywords) @api.onchange('show_description') def onchange_show_description(self): @@ -1140,6 +1147,9 @@ class PurchaseOrder(models.Model): break if send_email: + if self.is_local_env(): + _logger.warning("📪 Local environment detected — skip sending email reminders.") + return self._send_mail() if self.revisi_po: diff --git a/indoteknik_custom/models/sj_tele.py b/indoteknik_custom/models/sj_tele.py index 53ba26fc..ed363f59 100644 --- a/indoteknik_custom/models/sj_tele.py +++ b/indoteknik_custom/models/sj_tele.py @@ -5,6 +5,7 @@ import json import logging, subprocess import time from collections import OrderedDict +import socket _logger = logging.getLogger(__name__) @@ -20,7 +21,16 @@ class SjTele(models.Model): date_doc_kirim = fields.Datetime(string='Tanggal Kirim SJ') is_sent = fields.Boolean(default=False) + @staticmethod + def is_local_env(): + hostname = socket.gethostname().lower() + keywords = ['andri', 'miqdad', 'fin', 'stephan', 'hafid', 'nathan'] + return any(keyword in hostname for keyword in keywords) + def woi(self): + if self.is_local_env(): + _logger.warning("📪 Local environment detected — skip sending email reminders.") + return bot_mqdd = '8203414501:AAHy_XwiUAVrgRM2EJzW7sZx9npRLITZpb8' chat_id_mqdd = '-1003087280519' api_base = f'https://api.telegram.org/bot{bot_mqdd}' -- cgit v1.2.3 From 6074d548889ea0bcd489fcc6642eeaec1422cf89 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 18 Nov 2025 08:00:33 +0700 Subject: fix commission internal sales --- indoteknik_custom/models/commission_internal.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py index 66d32706..cd6da380 100644 --- a/indoteknik_custom/models/commission_internal.py +++ b/indoteknik_custom/models/commission_internal.py @@ -194,8 +194,8 @@ class CommissionInternal(models.Model): list_invoice.append(key) if key[:5] == 'SO/20': list_so.append(key) - invoices = self.env['account.move'].search([('state', '=', 'posted'), ('name', 'in', list_invoice)]) - orders = self.env['sale.order'].search([('state', 'in', ['done', 'sale']), ('name', 'in', list_so)]) + invoices = self.env['account.move'].search([('name', 'in', list_invoice)]) + orders = self.env['sale.order'].search([('name', 'in', list_so)]) invoice_data = invoices.mapped(lambda r: { 'res_name': 'account.move', 'res_id': r.id, @@ -216,6 +216,7 @@ class CommissionInternal(models.Model): 'helper1': line.helper1, 'commission_internal_id': line.commission_internal_id.id, 'commission_internal_line_id': line.id, + 'helper2': r.state, }) sale_data = orders.mapped(lambda r: { 'res_name': 'sale.order', @@ -237,6 +238,7 @@ class CommissionInternal(models.Model): 'helper1': line.helper1, 'commission_internal_id': line.commission_internal_id.id, 'commission_internal_line_id': line.id, + 'helper2': r.state, }) invoices_and_sales = invoice_data + sale_data sum_amount_total = sum(item['amount_total'] for item in invoices_and_sales) @@ -266,7 +268,8 @@ class CommissionInternal(models.Model): 'nomor_uang_masuk': data['nomor_uang_masuk'], 'uang_masuk': data['uang_masuk'], 'linenetamt_prorate': net_amount_prorate, - 'helper1': data['helper1'] + 'helper1': data['helper1'], + 'helper2': data['helper2'] }]) print(1) -- cgit v1.2.3 From 696a0ef4e25abd39a013503694be11ca2b0645ca Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 18 Nov 2025 10:14:25 +0700 Subject: (andri) add id transit CNY & HO --- indoteknik_custom/models/advance_payment_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index 42097923..d96fc8ee 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -1421,7 +1421,7 @@ class AdvancePaymentCreateBill(models.TransientModel): apr_id = fields.Many2one('advance.payment.request', string='Advance Payment Request', required=True) account_id = fields.Many2one( 'account.account', string='Bank Intransit', required=True, - domain="[('id', 'in', [573, 389, 392])]" # ID Bank Intransit + domain="[('id', 'in', [573, 389, 392, 683, 380])]" # ID Bank Intransit ) nominal = fields.Float(string='Nominal', related='apr_id.nominal') -- cgit v1.2.3 From ecdcf707992e0816a22619e7b87156eab8c9ed0c Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 18 Nov 2025 10:49:19 +0700 Subject: (andri) fix bug confirm payment PUM --- indoteknik_custom/models/advance_payment_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index d96fc8ee..ec23de63 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -505,7 +505,7 @@ class AdvancePaymentRequest(models.Model): for rec in self: if not rec.attachment_file_image and not rec.attachment_file_pdf: raise UserError( - f'Tidak bisa konfirmasi pembayaran PUM {rec.name or ""} ' + f'Tidak bisa konfirmasi pembayaran {rec.number or ""} ' f'karena belum ada bukti attachment (PDF/Image).' ) -- cgit v1.2.3 From 61a1d7e817de31b52285b6bf6448c321f1beac08 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 18 Nov 2025 11:34:19 +0700 Subject: tracking & readonly sales team --- indoteknik_custom/models/sale_order.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 14b66d87..2ed4046f 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -398,7 +398,10 @@ class SaleOrder(models.Model): compute="_compute_partner_is_cbd_locked" ) internal_notes_contact = fields.Text(related='partner_id.comment', string="Internal Notes", readonly=True, help="Internal Notes dari contact utama customer.") - is_so_fiktif = fields.Boolean('SO Fiktif?', tracking=3) + is_so_fiktif = fields.Boolean('SO Fiktif?', tracking=3) + team_id = fields.Many2one(tracking=True) + + def action_set_shipping_id(self): for rec in self: -- cgit v1.2.3 From b3e037e6d9f67e63803f6e56929f7c10b61074a3 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 18 Nov 2025 15:36:05 +0700 Subject: (andri) fix linked STJ PO --- indoteknik_custom/models/stock_picking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index f69e5fa9..e7686b75 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1541,9 +1541,9 @@ class StockPicking(models.Model): self.check_koli() res = super(StockPicking, self).button_validate() - # Penambahan link PO di Stock Journal untuk Picking BD + # Penambahan link PO di Stock Journal for picking in self: - if picking.name and 'BD/' in picking.name and picking.purchase_id: + if picking.name and picking.purchase_id: stock_journal = self.env['account.move'].search([ ('ref', 'ilike', picking.name + '%'), ('journal_id', '=', 3) # Stock Journal ID -- cgit v1.2.3