From 3176f8497009169294e25f7f461f1a81c6bd0c59 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 15 Apr 2025 11:23:52 +0700 Subject: push --- indoteknik_custom/models/delivery_order.py | 4 +-- indoteknik_custom/models/stock_picking.py | 47 +++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 12 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/delivery_order.py b/indoteknik_custom/models/delivery_order.py index 3473197b..2fc574c4 100644 --- a/indoteknik_custom/models/delivery_order.py +++ b/indoteknik_custom/models/delivery_order.py @@ -24,7 +24,7 @@ class DeliveryOrder(models.TransientModel): for delivery_order_line in vals['delivery_order_line_ids']: picking = False if delivery_order_line[2]['name']: - picking = self.env['stock.picking'].search([('picking_code', '=', delivery_order_line[2]['name'])], limit=1) + picking = self.env['stock.picking'].search([('out_code', '=', delivery_order_line[2]['name'])], limit=1) if picking: line_tracking_no = delivery_order_line[2]['tracking_no'] @@ -85,7 +85,7 @@ class DeliveryOrderLine(models.TransientModel): if self.name: if len(self.name) == 13: self.name = self.name[:-1] - picking = self.env['stock.picking'].search([('picking_code', '=', self.name)], limit=1) + picking = self.env['stock.picking'].search([('out_code', '=', self.name)], limit=1) if picking: if picking.driver_id: self.driver_id = picking.driver_id diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 8755a1f3..ae17b5d1 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -155,7 +155,32 @@ class StockPicking(models.Model): quantity_koli = fields.Float(string="Quantity Koli", copy=False) total_mapping_koli = fields.Float(string="Total Mapping Koli", compute='_compute_total_mapping_koli') so_lama = fields.Boolean('SO LAMA') - + linked_manual_bu_out = fields.Many2one('stock.picking', string='BU Out') + + # def write(self, vals): + # if 'linked_manual_bu_out' in vals: + # for record in self: + # if (record.picking_type_code == 'internal' + # and 'BU/PICK/' in record.name): + # # Jika menghapus referensi (nilai di-set False/None) + # if record.linked_manual_bu_out and not vals['linked_manual_bu_out']: + # record.linked_manual_bu_out.state_packing = 'not_packing' + # # Jika menambahkan referensi baru + # elif vals['linked_manual_bu_out']: + # new_picking = self.env['stock.picking'].browse(vals['linked_manual_bu_out']) + # new_picking.state_packing = 'packing_done' + # return super().write(vals) + + # @api.model + # def create(self, vals): + # record = super().create(vals) + # if (record.picking_type_code == 'internal' + # and 'BU/PICK/' in record.name + # and vals.get('linked_manual_bu_out')): + # picking = self.env['stock.picking'].browse(vals['linked_manual_bu_out']) + # picking.state_packing = 'packing_done' + # return record + @api.depends('konfirm_koli_lines', 'konfirm_koli_lines.pick_id', 'konfirm_koli_lines.pick_id.quantity_koli') def _compute_total_mapping_koli(self): for record in self: @@ -224,15 +249,6 @@ class StockPicking(models.Model): shipping_method_so_id = fields.Many2one('delivery.carrier', string='Shipping Method SO', related='sale_id.carrier_id') state_packing = fields.Selection([('not_packing', 'Belum Packing'), ('packing_done', 'Sudah Packing')], string='Packing Status') - @api.constrains('konfirm_koli_lines') - def _constrains_konfirm_koli_lines(self): - now = datetime.datetime.utcnow() - for picking in self: - if len(picking.konfirm_koli_lines) > 0: - picking.state_packing = 'packing_done' - else: - picking.state_packing = 'not_packing' - @api.constrains('scan_koli_lines') def _constrains_scan_koli_lines(self): now = datetime.datetime.utcnow() @@ -1265,6 +1281,17 @@ class StockPicking(models.Model): line.sale_line_id = sale_line.id def write(self, vals): + if 'linked_manual_bu_out' in vals: + for record in self: + if (record.picking_type_code == 'internal' + and 'BU/PICK/' in record.name): + # Jika menghapus referensi (nilai di-set False/None) + if record.linked_manual_bu_out and not vals['linked_manual_bu_out']: + record.linked_manual_bu_out.state_packing = 'not_packing' + # Jika menambahkan referensi baru + elif vals['linked_manual_bu_out']: + new_picking = self.env['stock.picking'].browse(vals['linked_manual_bu_out']) + new_picking.state_packing = 'packing_done' self._use_faktur(vals) self.sync_sale_line(vals) for picking in self: -- cgit v1.2.3 From d04df4f0f78e34dbaf1ce7f8ea1102ac2bdf019c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 15 Apr 2025 11:41:14 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index ae17b5d1..383c75a3 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1030,6 +1030,9 @@ class StockPicking(models.Model): if len(self.check_koli_lines) == 0 and 'BU/PICK/' in self.name: raise UserError(_("Tidak ada koli! Harap periksa kembali.")) + if not self.linked_manual_bu_out and 'BU/PICK/' in self.name: + raise UserError(_("Isi BU Out terlebih dahulu!")) + if len(self.check_product_lines) == 0 and 'BU/PICK/' in self.name: raise UserError(_("Tidak ada Check Product! Harap periksa kembali.")) @@ -1090,7 +1093,6 @@ class StockPicking(models.Model): res = super(StockPicking, self).button_validate() self.calculate_line_no() self.date_done = datetime.datetime.utcnow() - self.driver_departure_date = datetime.datetime.utcnow() self.state_reserve = 'done' self.final_seq = 0 self.set_picking_code_out() -- cgit v1.2.3 From e9f38f540f92d6ef98b0153cbf17ce064932ad60 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Tue, 15 Apr 2025 16:47:04 +0700 Subject: fix: add minimun delivery_amt + alert --- indoteknik_custom/models/sale_order.py | 80 ++++++++++++++++++++++++++++++++-- 1 file changed, 76 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 c83ffd61..36feb70b 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -315,8 +315,12 @@ class SaleOrder(models.Model): "sale_order_id": self.id, }) self.shipping_option_id = shipping_option.id - + def action_estimate_shipping(self): + # Pengecekan Minimum Delivery Amount + if self.delivery_amt < 5000: + raise UserError("Estimasi ongkos kirim belum mencapai jumlah minimum untuk pengiriman") + if self.carrier_id.id in [1, 151]: self.action_indoteknik_estimate_shipping() return @@ -366,10 +370,65 @@ class SaleOrder(models.Model): self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id - self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}") + # Jika perlu, tambahkan log atau tindakan lebih lanjut setelah peringatan else: raise UserError("Gagal mendapatkan estimasi ongkir.") + + # def action_estimate_shipping(self): + # if self.carrier_id.id in [1, 151]: + # self.action_indoteknik_estimate_shipping() + # return + + # total_weight = 0 + # missing_weight_products = [] + + # for line in self.order_line: + # if line.weight > 0: + # total_weight += line.weight * line.product_uom_qty + # line.product_id.weight = line.weight + # else: + # missing_weight_products.append(line.product_id.name) + + # if missing_weight_products: + # product_names = '
'.join(missing_weight_products) + # self.message_post(body=f"Produk berikut tidak memiliki berat:
{product_names}") + + # if total_weight == 0: + # raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") + + # destination_subsdistrict_id = self.real_shipping_id.kecamatan_id.rajaongkir_id + # if not destination_subsdistrict_id: + # raise UserError("Gagal mendapatkan ID kota tujuan.") + + # result = self._call_rajaongkir_api(total_weight, destination_subsdistrict_id) + # if result: + # shipping_options = [] + # for courier in result['rajaongkir']['results']: + # for cost_detail in courier['costs']: + # service = cost_detail['service'] + # description = cost_detail['description'] + # etd = cost_detail['cost'][0]['etd'] + # value = cost_detail['cost'][0]['value'] + # shipping_options.append((service, description, etd, value, courier['code'])) + + # self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() + + # for service, description, etd, value, provider in shipping_options: + # self.env["shipping.option"].create({ + # "name": service, + # "price": value, + # "provider": provider, + # "etd": etd, + # "sale_order_id": self.id, + # }) + + # self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id + + # self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}") + # else: + # raise UserError("Gagal mendapatkan estimasi ongkir.") + def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id): url = 'https://pro.rajaongkir.com/api/cost' headers = { @@ -670,13 +729,26 @@ class SaleOrder(models.Model): raise UserError('Email yang anda input kurang valid') # @api.constrains('delivery_amt', 'carrier_id', 'shipping_cost_covered') + def _validate_delivery_amt(self): + if self.delivery_amt < 5000: + raise UserError("Estimasi Ongkos Kirim belum memenuhi jumlah minimum untuk pengiriman.") + if self.delivery_amt < 1: - if(self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): - if(self.carrier_id.id == 1): + if (self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): + if self.carrier_id.id == 1: raise UserError('Untuk Kurir Indoteknik Delivery, Estimasi Ongkos Kirim Harus di isi') else: raise UserError('Untuk Shipping Covered Indoteknik, Estimasi Ongkos Kirim Harus di isi') + + + # def _validate_delivery_amt(self): + # if self.delivery_amt < 1: + # if(self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): + # if(self.carrier_id.id == 1): + # raise UserError('Untuk Kurir Indoteknik Delivery, Estimasi Ongkos Kirim Harus di isi') + # else: + # raise UserError('Untuk Shipping Covered Indoteknik, Estimasi Ongkos Kirim Harus di isi') def override_allow_create_invoice(self): if not self.env.user.is_accounting: -- cgit v1.2.3 From ceba13a481818a7832f4c89035248abf21b94940 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Apr 2025 09:27:05 +0700 Subject: push --- indoteknik_custom/models/delivery_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/delivery_order.py b/indoteknik_custom/models/delivery_order.py index 2fc574c4..3473197b 100644 --- a/indoteknik_custom/models/delivery_order.py +++ b/indoteknik_custom/models/delivery_order.py @@ -24,7 +24,7 @@ class DeliveryOrder(models.TransientModel): for delivery_order_line in vals['delivery_order_line_ids']: picking = False if delivery_order_line[2]['name']: - picking = self.env['stock.picking'].search([('out_code', '=', delivery_order_line[2]['name'])], limit=1) + picking = self.env['stock.picking'].search([('picking_code', '=', delivery_order_line[2]['name'])], limit=1) if picking: line_tracking_no = delivery_order_line[2]['tracking_no'] @@ -85,7 +85,7 @@ class DeliveryOrderLine(models.TransientModel): if self.name: if len(self.name) == 13: self.name = self.name[:-1] - picking = self.env['stock.picking'].search([('out_code', '=', self.name)], limit=1) + picking = self.env['stock.picking'].search([('picking_code', '=', self.name)], limit=1) if picking: if picking.driver_id: self.driver_id = picking.driver_id -- cgit v1.2.3 From f1968b89ca7a32a69150fc6f9a4f848582d13336 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Apr 2025 09:55:13 +0700 Subject: push --- indoteknik_custom/models/delivery_order.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/delivery_order.py b/indoteknik_custom/models/delivery_order.py index 3473197b..aa9c42c2 100644 --- a/indoteknik_custom/models/delivery_order.py +++ b/indoteknik_custom/models/delivery_order.py @@ -25,7 +25,8 @@ class DeliveryOrder(models.TransientModel): picking = False if delivery_order_line[2]['name']: picking = self.env['stock.picking'].search([('picking_code', '=', delivery_order_line[2]['name'])], limit=1) - + if picking: + picking = self.env['stock.picking'].search([('out_code', '=', delivery_order_line[2]['name'])], limit=1) if picking: line_tracking_no = delivery_order_line[2]['tracking_no'] @@ -86,6 +87,10 @@ class DeliveryOrderLine(models.TransientModel): if len(self.name) == 13: self.name = self.name[:-1] picking = self.env['stock.picking'].search([('picking_code', '=', self.name)], limit=1) + + if not picking: + picking = self.env['stock.picking'].search([('out_code', '=', self.name)], limit=1) + if picking: if picking.driver_id: self.driver_id = picking.driver_id -- cgit v1.2.3 From 041bcaaf06a6824493b02cf9dfc1b9d4fa09c6c9 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Apr 2025 10:14:54 +0700 Subject: fix bug --- indoteknik_custom/models/delivery_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/delivery_order.py b/indoteknik_custom/models/delivery_order.py index aa9c42c2..2dd0c802 100644 --- a/indoteknik_custom/models/delivery_order.py +++ b/indoteknik_custom/models/delivery_order.py @@ -25,7 +25,7 @@ class DeliveryOrder(models.TransientModel): picking = False if delivery_order_line[2]['name']: picking = self.env['stock.picking'].search([('picking_code', '=', delivery_order_line[2]['name'])], limit=1) - if picking: + if not picking: picking = self.env['stock.picking'].search([('out_code', '=', delivery_order_line[2]['name'])], limit=1) if picking: line_tracking_no = delivery_order_line[2]['tracking_no'] -- cgit v1.2.3 From 2dc56ffaf7e2e6d703eac32fd1213cf84b684915 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 16 Apr 2025 10:25:39 +0700 Subject: (andri)add log note after estimate shipping success --- indoteknik_custom/models/sale_order.py | 129 +++++++++++++-------------------- 1 file changed, 51 insertions(+), 78 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 36feb70b..cc7b9851 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -315,12 +315,22 @@ class SaleOrder(models.Model): "sale_order_id": self.id, }) self.shipping_option_id = shipping_option.id + self.message_post( + body=( + f"Estimasi pengiriman Indoteknik berhasil:
" + f"Layanan: {shipping_option.name}
" + f"ETD: {shipping_option.etd}
" + f"Biaya: Rp {shipping_option.price:,}
" + f"Provider: {shipping_option.provider}" + ), + message_type="comment", + ) def action_estimate_shipping(self): # Pengecekan Minimum Delivery Amount if self.delivery_amt < 5000: raise UserError("Estimasi ongkos kirim belum mencapai jumlah minimum untuk pengiriman") - + if self.carrier_id.id in [1, 151]: self.action_indoteknik_estimate_shipping() return @@ -347,87 +357,50 @@ class SaleOrder(models.Model): raise UserError("Gagal mendapatkan ID kota tujuan.") result = self._call_rajaongkir_api(total_weight, destination_subsdistrict_id) - if result: - shipping_options = [] - for courier in result['rajaongkir']['results']: - for cost_detail in courier['costs']: - service = cost_detail['service'] - description = cost_detail['description'] - etd = cost_detail['cost'][0]['etd'] - value = cost_detail['cost'][0]['value'] - shipping_options.append((service, description, etd, value, courier['code'])) - - self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() - - for service, description, etd, value, provider in shipping_options: - self.env["shipping.option"].create({ - "name": service, - "price": value, - "provider": provider, - "etd": etd, - "sale_order_id": self.id, - }) - - self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id - # Jika perlu, tambahkan log atau tindakan lebih lanjut setelah peringatan + if not result: + raise UserError("Estimasi Ongkir gagal sebab pilihan kurir tidak terdaftar di RajaOngkir") + + shipping_options = [] + for courier in result['rajaongkir']['results']: + for cost_detail in courier['costs']: + service = cost_detail['service'] + description = cost_detail['description'] + etd = cost_detail['cost'][0]['etd'] + value = cost_detail['cost'][0]['value'] + shipping_options.append((service, description, etd, value, courier['code'])) + + # Hapus opsi shipping lama + self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() + + # Simpan opsi shipping baru + for service, description, etd, value, provider in shipping_options: + self.env["shipping.option"].create({ + "name": service, + "price": value, + "provider": provider, + "etd": etd, + "sale_order_id": self.id, + }) + + # Set opsi shipping default + first_option = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1) + if first_option: + self.shipping_option_id = first_option.id + message = ( + f"Estimasi pengiriman berhasil:
" + f"Layanan: {first_option.name}
" + f"Deskripsi: {dict(first_option._fields['name'].selection).get(first_option.name, first_option.name)}
" + f"ETD: {first_option.etd} hari
" + f"Biaya: Rp {first_option.price:,}" + ) + self.message_post( + body=message, + message_type="comment", + ) else: raise UserError("Gagal mendapatkan estimasi ongkir.") - - # def action_estimate_shipping(self): - # if self.carrier_id.id in [1, 151]: - # self.action_indoteknik_estimate_shipping() - # return - - # total_weight = 0 - # missing_weight_products = [] - - # for line in self.order_line: - # if line.weight > 0: - # total_weight += line.weight * line.product_uom_qty - # line.product_id.weight = line.weight - # else: - # missing_weight_products.append(line.product_id.name) - - # if missing_weight_products: - # product_names = '
'.join(missing_weight_products) - # self.message_post(body=f"Produk berikut tidak memiliki berat:
{product_names}") - - # if total_weight == 0: - # raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.") - - # destination_subsdistrict_id = self.real_shipping_id.kecamatan_id.rajaongkir_id - # if not destination_subsdistrict_id: - # raise UserError("Gagal mendapatkan ID kota tujuan.") - - # result = self._call_rajaongkir_api(total_weight, destination_subsdistrict_id) - # if result: - # shipping_options = [] - # for courier in result['rajaongkir']['results']: - # for cost_detail in courier['costs']: - # service = cost_detail['service'] - # description = cost_detail['description'] - # etd = cost_detail['cost'][0]['etd'] - # value = cost_detail['cost'][0]['value'] - # shipping_options.append((service, description, etd, value, courier['code'])) - - # self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() - - # for service, description, etd, value, provider in shipping_options: - # self.env["shipping.option"].create({ - # "name": service, - # "price": value, - # "provider": provider, - # "etd": etd, - # "sale_order_id": self.id, - # }) - - # self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id - - # self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}") - # else: - # raise UserError("Gagal mendapatkan estimasi ongkir.") def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id): url = 'https://pro.rajaongkir.com/api/cost' -- cgit v1.2.3 From 0a5e1713cee2cec10863c77fe930e8985da62d16 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Apr 2025 11:02:00 +0700 Subject: push --- indoteknik_custom/models/logbook_sj.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/logbook_sj.py b/indoteknik_custom/models/logbook_sj.py index 9f349882..75b2622f 100644 --- a/indoteknik_custom/models/logbook_sj.py +++ b/indoteknik_custom/models/logbook_sj.py @@ -26,6 +26,8 @@ class LogbookSJ(models.TransientModel): report_logbook = self.env['report.logbook.sj'].create([parameters_header]) for line in logbook_line: picking = self.env['stock.picking'].search([('picking_code', '=', line.name)], limit=1) + if not picking: + picking = self.env['stock.picking'].search([('out_code', '=', line.name)], limit=1) stock = picking parent_id = stock.partner_id.parent_id.id parent_id = parent_id if parent_id else stock.partner_id.id @@ -80,6 +82,9 @@ class LogbookSJLine(models.TransientModel): if len(self.name) == 13: self.name = self.name[:-1] picking = self.env['stock.picking'].search([('picking_code', '=', self.name)], limit=1) + + if not picking: + picking = self.env['stock.picking'].search([('out_code', '=', self.name)], limit=1) if picking: if picking.driver_id: self.driver_id = picking.driver_id -- cgit v1.2.3 From 6ee875d5dad299ebcd17c16d6c3736cf881e53f4 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Apr 2025 11:30:28 +0700 Subject: ppush --- 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 c83ffd61..97e3b5b0 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -472,7 +472,7 @@ class SaleOrder(models.Model): def _compute_date_kirim(self): for rec in self: - picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel'])], order='date_doc_kirim desc', limit=1) + picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel']), ('name', 'not ilike', 'BU/PICK/%')], order='date_doc_kirim desc', limit=1) rec.date_kirim_ril = picking.date_doc_kirim rec.date_status_done = picking.date_done rec.date_driver_arrival = picking.driver_arrival_date -- cgit v1.2.3 From 0ee640e0030441c204be6de3edc4184a37c85cd8 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 16 Apr 2025 11:46:43 +0700 Subject: (andri) add min & max NPWP --- indoteknik_custom/models/res_partner.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index fd3a0514..04ee136c 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -104,7 +104,7 @@ class ResPartner(models.Model): ('nonpkp', 'Non PKP') ]) sppkp = fields.Char(string="SPPKP", tracking=True) - npwp = fields.Char(string="NPWP", tracking=True) + npwp = fields.Char(string="npwp", tracking=True) nitku = fields.Char(string="NITKU", tracking=True) counter = fields.Integer(string="Counter", default=0) leadtime = fields.Integer(string="Leadtime", default=0) @@ -200,6 +200,17 @@ class ResPartner(models.Model): if existing_partner: raise ValidationError(f"Nama '{record.name}' sudah digunakan oleh partner lain!") + @api.constrains('npwp') + def _check_npwp(self): + for rec in self: + if rec.npwp: + if not rec.npwp.isdigit(): + raise ValidationError("NPWP hanya boleh berisi angka.") + if len(rec.npwp) <= 15: + raise UserError("NPWP terlalu pendek. Minimal 15 digit.") + if len(rec.npwp) >= 16: + raise ValidationError("NPWP terlalu panjang. Maksimal 16 digit.") + def write(self, vals): # Fungsi rekursif untuk meng-update semua child, termasuk child dari child def update_children_recursively(partner, vals_for_child): -- cgit v1.2.3 From e2a9f4f82b0c761cc4c20d501ab586239c0126a3 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Apr 2025 11:51:03 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 383c75a3..3aa3a0a4 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1542,9 +1542,22 @@ class CheckProduct(models.Model): index=True, copy=False, ) - product_id = fields.Many2one('product.product', string='Product', required=True) - quantity = fields.Float(string='Quantity', default=1.0, required=True) + product_id = fields.Many2one('product.product', string='Product') + quantity = fields.Float(string='Quantity', default=1.0) status = fields.Char(string='Status', compute='_compute_status') + code_product = fields.Char(string='Code Product') + + @api.onchange('code_product') + def _onchange_code_product(self): + if self.code_product: + product = self.env['product.product'].search([('default_code', '=', self.code_product)], limit=1) + if not product: + product = self.env['product.product'].search([('barcode', '=', self.code_product)], limit=1) + + if product: + self.product_id = product.id + else: + raise UserError("Product tidak ditemukan") @api.depends('quantity') def _compute_status(self): @@ -1654,13 +1667,13 @@ class CheckProduct(models.Model): # Calculate the total quantity after addition total_quantity = sum(existing_lines.mapped('quantity')) - record.quantity - if total_quantity > total_qty_in_moves: + if total_quantity == total_qty_in_moves: raise UserError(( "Quantity Product '%s' sudah melebihi quantity demand." ) % (record.product_id.display_name)) else: # Check if the quantity exceeds the allowed total - if record.quantity > total_qty_in_moves: + if record.quantity == total_qty_in_moves: raise UserError(( "Quantity Product '%s' sudah melebihi quantity demand." ) % (record.product_id.display_name)) @@ -1741,6 +1754,16 @@ class ScanKoli(models.Model): string="Progress Scan Koli", compute="_compute_scan_koli_progress" ) + code_koli = fields.Char(string='Code Koli') + + @api.onchange('code_koli') + def _onchange_code_koli(self): + if self.code_koli: + koli = self.env['sales.order.koli'].search([('koli_id.koli', '=', self.code_koli)], limit=1) + if koli: + self.write({'koli_id': koli.id}) + else: + raise UserError('Koli tidak ditemukan') def _compute_scan_koli_progress(self): for scan in self: -- cgit v1.2.3 From e903492969baf706e73fca2a2a85168dfb815219 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 16 Apr 2025 14:58:43 +0700 Subject: fix bug --- indoteknik_custom/models/stock_picking.py | 34 +++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 3aa3a0a4..85428aa0 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1765,14 +1765,14 @@ class ScanKoli(models.Model): else: raise UserError('Koli tidak ditemukan') - def _compute_scan_koli_progress(self): - for scan in self: - if scan.picking_id: - all_scans = self.env['scan.koli'].search([('picking_id', '=', scan.picking_id.id)], order='id') - if all_scans: - scan_index = list(all_scans).index(scan) + 1 # Nomor urut scan - total_so_koli = scan.picking_id.total_so_koli - scan.scan_koli_progress = f"{scan_index}/{total_so_koli}" if total_so_koli else "0/0" + # def _compute_scan_koli_progress(self): + # for scan in self: + # if scan.picking_id: + # all_scans = self.env['scan.koli'].search([('picking_id', '=', scan.picking_id.id)], order='id') + # if all_scans: + # scan_index = list(all_scans).index(scan) + 1 # Nomor urut scan + # total_so_koli = scan.picking_id.total_so_koli + # scan.scan_koli_progress = f"{scan_index}/{total_so_koli}" if total_so_koli else "0/0" @api.onchange('koli_id') def _onchange_koli_compare_with_konfirm_koli(self): @@ -1844,13 +1844,21 @@ class ScanKoli(models.Model): def _compute_scan_koli_progress(self): for scan in self: - if scan.picking_id: + if not scan.picking_id: + scan.scan_koli_progress = "0/0" + continue + + try: all_scans = self.env['scan.koli'].search([('picking_id', '=', scan.picking_id.id)], order='id') if all_scans: - scan_index = list(all_scans).index(scan) + 1 # Nomor urut scan - total_so_koli = scan.picking_id.total_so_koli - scan.scan_koli_progress = f"{scan_index}/{total_so_koli}" if total_so_koli else "0/0" - + scan_index = list(all_scans).index(scan) + 1 + total_so_koli = scan.picking_id.total_so_koli or 0 + scan.scan_koli_progress = f"{scan_index}/{total_so_koli}" + else: + scan.scan_koli_progress = "0/0" + except Exception: + # Fallback in case of any error + scan.scan_koli_progress = "0/0" @api.constrains('picking_id', 'picking_id.total_so_koli') def _check_koli_validation(self): for scan in self.picking_id.scan_koli_lines: -- cgit v1.2.3 From 30f5cdf7b2537093d9759c49ba027ffd0608acb9 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 17 Apr 2025 08:38:17 +0700 Subject: push --- 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 85428aa0..97607502 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1667,13 +1667,13 @@ class CheckProduct(models.Model): # Calculate the total quantity after addition total_quantity = sum(existing_lines.mapped('quantity')) - record.quantity - if total_quantity == total_qty_in_moves: + if total_quantity > total_qty_in_moves: raise UserError(( "Quantity Product '%s' sudah melebihi quantity demand." ) % (record.product_id.display_name)) else: # Check if the quantity exceeds the allowed total - if record.quantity == total_qty_in_moves: + if record.quantity > total_qty_in_moves: raise UserError(( "Quantity Product '%s' sudah melebihi quantity demand." ) % (record.product_id.display_name)) -- cgit v1.2.3 From de6450a17a85c063fe49705991098116efccae75 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 17 Apr 2025 10:49:27 +0700 Subject: push --- 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 97607502..85428aa0 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1667,13 +1667,13 @@ class CheckProduct(models.Model): # Calculate the total quantity after addition total_quantity = sum(existing_lines.mapped('quantity')) - record.quantity - if total_quantity > total_qty_in_moves: + if total_quantity == total_qty_in_moves: raise UserError(( "Quantity Product '%s' sudah melebihi quantity demand." ) % (record.product_id.display_name)) else: # Check if the quantity exceeds the allowed total - if record.quantity > total_qty_in_moves: + if record.quantity == total_qty_in_moves: raise UserError(( "Quantity Product '%s' sudah melebihi quantity demand." ) % (record.product_id.display_name)) -- cgit v1.2.3 From 984c3fe0d032dc0e37aae030b10658c310b9705d Mon Sep 17 00:00:00 2001 From: AndriFP Date: Thu, 17 Apr 2025 13:50:10 +0700 Subject: (andri) Check + revisi add minimum dev amt & add log note after estimate shipping --- indoteknik_custom/models/res_partner.py | 16 ++--- indoteknik_custom/models/sale_order.py | 108 +++++++++++++++----------------- 2 files changed, 60 insertions(+), 64 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 04ee136c..451577c5 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -104,7 +104,7 @@ class ResPartner(models.Model): ('nonpkp', 'Non PKP') ]) sppkp = fields.Char(string="SPPKP", tracking=True) - npwp = fields.Char(string="npwp", tracking=True) + npwp = fields.Char(string="NPWP", tracking=True) nitku = fields.Char(string="NITKU", tracking=True) counter = fields.Integer(string="Counter", default=0) leadtime = fields.Integer(string="Leadtime", default=0) @@ -202,14 +202,14 @@ class ResPartner(models.Model): @api.constrains('npwp') def _check_npwp(self): - for rec in self: - if rec.npwp: - if not rec.npwp.isdigit(): + for record in self: + if record.npwp: + if not record.npwp.isdigit(): raise ValidationError("NPWP hanya boleh berisi angka.") - if len(rec.npwp) <= 15: - raise UserError("NPWP terlalu pendek. Minimal 15 digit.") - if len(rec.npwp) >= 16: - raise ValidationError("NPWP terlalu panjang. Maksimal 16 digit.") + if len(record.npwp) < 15: + raise ValidationError("Digit NPWP yang dimasukkan kurang dari batas minimal (15 digit)") + if len(record.npwp) > 16: + raise ValidationError("Digit NPWP yang dimasukkan lebih dari batas maksimal (16 digit)") def write(self, vals): # Fungsi rekursif untuk meng-update semua child, termasuk child dari child diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index cc7b9851..92581678 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -327,10 +327,6 @@ class SaleOrder(models.Model): ) def action_estimate_shipping(self): - # Pengecekan Minimum Delivery Amount - if self.delivery_amt < 5000: - raise UserError("Estimasi ongkos kirim belum mencapai jumlah minimum untuk pengiriman") - if self.carrier_id.id in [1, 151]: self.action_indoteknik_estimate_shipping() return @@ -357,50 +353,45 @@ class SaleOrder(models.Model): raise UserError("Gagal mendapatkan ID kota tujuan.") result = self._call_rajaongkir_api(total_weight, destination_subsdistrict_id) + if result: + shipping_options = [] + for courier in result['rajaongkir']['results']: + for cost_detail in courier['costs']: + service = cost_detail['service'] + description = cost_detail['description'] + etd = cost_detail['cost'][0]['etd'] + value = cost_detail['cost'][0]['value'] + shipping_options.append((service, description, etd, value, courier['code'])) + + self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() - if not result: - raise UserError("Estimasi Ongkir gagal sebab pilihan kurir tidak terdaftar di RajaOngkir") - - shipping_options = [] - for courier in result['rajaongkir']['results']: - for cost_detail in courier['costs']: - service = cost_detail['service'] - description = cost_detail['description'] - etd = cost_detail['cost'][0]['etd'] - value = cost_detail['cost'][0]['value'] - shipping_options.append((service, description, etd, value, courier['code'])) - - # Hapus opsi shipping lama - self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() - - # Simpan opsi shipping baru - for service, description, etd, value, provider in shipping_options: - self.env["shipping.option"].create({ - "name": service, - "price": value, - "provider": provider, - "etd": etd, - "sale_order_id": self.id, - }) + _logger.info(f"Shipping options: {shipping_options}") + + for service, description, etd, value, provider in shipping_options: + self.env["shipping.option"].create({ + "name": service, + "price": value, + "provider": provider, + "etd": etd, + "sale_order_id": self.id, + }) + + + self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id + + _logger.info(f"Shipping option SO ID: {self.shipping_option_id}") - # Set opsi shipping default - first_option = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1) - if first_option: - self.shipping_option_id = first_option.id - message = ( - f"Estimasi pengiriman berhasil:
" - f"Layanan: {first_option.name}
" - f"Deskripsi: {dict(first_option._fields['name'].selection).get(first_option.name, first_option.name)}
" - f"ETD: {first_option.etd} hari
" - f"Biaya: Rp {first_option.price:,}" - ) self.message_post( - body=message, - message_type="comment", + body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
" + f"{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}", + message_type="comment" ) + + # self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}", message_type="comment") + else: raise UserError("Gagal mendapatkan estimasi ongkir.") - + def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id): url = 'https://pro.rajaongkir.com/api/cost' @@ -702,26 +693,31 @@ class SaleOrder(models.Model): raise UserError('Email yang anda input kurang valid') # @api.constrains('delivery_amt', 'carrier_id', 'shipping_cost_covered') - def _validate_delivery_amt(self): - if self.delivery_amt < 5000: - raise UserError("Estimasi Ongkos Kirim belum memenuhi jumlah minimum untuk pengiriman.") + is_indoteknik = self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik' + is_active_id = not self.env.context.get('active_id', []) - if self.delivery_amt < 1: - if (self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): + if is_indoteknik and is_active_id: + if self.delivery_amt == 0: if self.carrier_id.id == 1: - raise UserError('Untuk Kurir Indoteknik Delivery, Estimasi Ongkos Kirim Harus di isi') + raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum diisi.') else: - raise UserError('Untuk Shipping Covered Indoteknik, Estimasi Ongkos Kirim Harus di isi') + raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum diisi.') + + if self.delivery_amt < 5000: + if self.carrier_id.id == 1: + raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi tarif minimum.') + else: + raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi tarif minimum.') + + # if self.delivery_amt < 5000: + # if (self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): + # if self.carrier_id.id == 1: + # raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi jumlah minimum.') + # else: + # raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi jumlah minimum.') - # def _validate_delivery_amt(self): - # if self.delivery_amt < 1: - # if(self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): - # if(self.carrier_id.id == 1): - # raise UserError('Untuk Kurir Indoteknik Delivery, Estimasi Ongkos Kirim Harus di isi') - # else: - # raise UserError('Untuk Shipping Covered Indoteknik, Estimasi Ongkos Kirim Harus di isi') def override_allow_create_invoice(self): if not self.env.user.is_accounting: -- cgit v1.2.3 From fcb65326ffd7daf6136a97b53cca5493964d94aa Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 17 Apr 2025 17:06:30 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 85428aa0..f04b0e79 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1559,6 +1559,34 @@ class CheckProduct(models.Model): else: raise UserError("Product tidak ditemukan") + def unlink(self): + # Get all affected pickings before deletion + pickings = self.mapped('picking_id') + + # Store product_ids that will be deleted + deleted_product_ids = self.mapped('product_id') + + # Perform the deletion + result = super(CheckProduct, self).unlink() + + # After deletion, update moves for affected pickings + for picking in pickings: + # For products that were completely removed (no remaining check.product lines) + remaining_product_ids = picking.check_product_lines.mapped('product_id') + removed_product_ids = deleted_product_ids - remaining_product_ids + + # Set quantity_done to 0 for moves of completely removed products + moves_to_reset = picking.move_ids_without_package.filtered( + lambda move: move.product_id in removed_product_ids + ) + for move in moves_to_reset: + move.quantity_done = 0.0 + + # Also sync remaining products in case their totals changed + self._sync_check_product_to_moves(picking) + + return result + @api.depends('quantity') def _compute_status(self): for record in self: -- cgit v1.2.3 From 7545da8fdc9fc01fe9b2bd2a4612ae22d0be8e57 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 19 Apr 2025 11:59:01 +0700 Subject: add constrains date doc kirim to update calculate line no --- indoteknik_custom/models/stock_picking.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index f04b0e79..923c56f5 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -248,6 +248,11 @@ class StockPicking(models.Model): final_seq = fields.Float(string='Remaining Time') shipping_method_so_id = fields.Many2one('delivery.carrier', string='Shipping Method SO', related='sale_id.carrier_id') state_packing = fields.Selection([('not_packing', 'Belum Packing'), ('packing_done', 'Sudah Packing')], string='Packing Status') + + @api.constrains('date_doc_kirim') + def _constrains_date_doc_kirim(self): + for rec in self: + rec.calculate_line_no() @api.constrains('scan_koli_lines') def _constrains_scan_koli_lines(self): @@ -1091,7 +1096,6 @@ class StockPicking(models.Model): if self.picking_type_code == 'outgoing' and 'BU/OUT/' in self.name: self.check_koli() res = super(StockPicking, self).button_validate() - self.calculate_line_no() self.date_done = datetime.datetime.utcnow() self.state_reserve = 'done' self.final_seq = 0 -- cgit v1.2.3 From ad139f4c1613f4571074006276d29448bfe95ff8 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Mon, 21 Apr 2025 14:11:46 +0700 Subject: (andrifp) fix validate NPWP --- indoteknik_custom/models/res_partner.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 451577c5..06945301 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -39,6 +39,10 @@ class ResPartner(models.Model): estimasi_tempo = fields.Char(string='Estimasi Pembelian Pertahun') tempo_duration = fields.Many2one('account.payment.term', string='Durasi Tempo') tempo_limit = fields.Char(string='Limit Tempo') + minimum_amount = fields.Float( + string="Minimum Order", + help="Jika total belanja kurang dari ini, maka payment term akan otomatis menjadi CBD." + ) category_produk_ids = fields.Many2many('product.public.category', string='Kategori Produk yang Digunakan', domain=lambda self: self._get_default_category_domain()) @api.model @@ -203,13 +207,14 @@ class ResPartner(models.Model): @api.constrains('npwp') def _check_npwp(self): for record in self: - if record.npwp: - if not record.npwp.isdigit(): - raise ValidationError("NPWP hanya boleh berisi angka.") - if len(record.npwp) < 15: - raise ValidationError("Digit NPWP yang dimasukkan kurang dari batas minimal (15 digit)") - if len(record.npwp) > 16: - raise ValidationError("Digit NPWP yang dimasukkan lebih dari batas maksimal (16 digit)") + npwp = record.npwp.strip() if record.npwp else '' + # Abaikan validasi jika NPWP kosong atau diisi "0" + if not npwp or npwp == '0' or npwp == '00.000.000.0-000.000': + continue + if len(npwp) < 15: + raise ValidationError("Digit NPWP yang dimasukkan kurang dari batas minimal (15 digit)") + if len(npwp) > 16: + raise ValidationError("Digit NPWP yang dimasukkan lebih dari batas maksimal (16 digit)") def write(self, vals): # Fungsi rekursif untuk meng-update semua child, termasuk child dari child @@ -476,6 +481,8 @@ class ResPartner(models.Model): def _onchange_customer_type(self): if self.customer_type == 'nonpkp': self.npwp = '00.000.000.0-000.000' + elif self.customer_type == 'pkp': + self.npwp = '00.000.000.0-000.000' def get_check_payment_term(self): self.ensure_one() -- cgit v1.2.3 From cd51ac345b0898034428aab3b8ded24d03c0fdfd Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 21 Apr 2025 15:06:14 +0700 Subject: approval invoice date --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/approval_invoice_date.py | 46 +++++++++++++++++++++++ indoteknik_custom/models/stock_picking.py | 40 +++++++++++++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/approval_invoice_date.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 935a0aa0..08fa9803 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -149,3 +149,4 @@ from . import sales_order_koli from . import stock_backorder_confirmation from . import account_payment_register from . import stock_inventory +from . import approval_invoice_date diff --git a/indoteknik_custom/models/approval_invoice_date.py b/indoteknik_custom/models/approval_invoice_date.py new file mode 100644 index 00000000..48546e55 --- /dev/null +++ b/indoteknik_custom/models/approval_invoice_date.py @@ -0,0 +1,46 @@ +from odoo import models, api, fields +from odoo.exceptions import AccessError, UserError, ValidationError +from datetime import timedelta, date, datetime +import logging + +_logger = logging.getLogger(__name__) + +class ApprovalInvoiceDate(models.Model): + _name = "approval.invoice.date" + _description = "Approval Invoice Date" + _rec_name = 'number' + + picking_id = fields.Many2one('stock.picking', string='Picking') + number = fields.Char(string='Document No', index=True, copy=False, readonly=True, tracking=True) + date_invoice = fields.Datetime( + string='Invoice Date', + copy=False + ) + date_doc_do = fields.Datetime( + string='Tanggal Kirim di SJ', + copy=False + ) + state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancel')], string='State', default='draft', tracking=True) + approve_date = fields.Datetime(string='Approve Date', copy=False) + approve_by = fields.Many2one('res.users', string='Approve By', copy=False) + sale_id = fields.Many2one('sale.order', string='Sale Order') + partner_id = fields.Many2one('res.partner', string='Partner') + move_id = fields.Many2one('account.move', string='Invoice') + note = fields.Char(string='Note') + + def button_approve(self): + if not self.env.user.is_accounting: + raise UserError("Hanya Accounting Yang Bisa Approve") + self.move_id.invoice_date = self.date_doc_do + self.state = 'done' + self.approve_date = datetime.utcnow() + self.approve_by = self.env.user.id + + def button_cancel(self): + self.state = 'cancel' + + @api.model + def create(self, vals): + vals['number'] = self.env['ir.sequence'].next_by_code('approval.invoice.date') or '0' + result = super(ApprovalInvoiceDate, self).create(vals) + return result diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 923c56f5..0701a989 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -248,11 +248,40 @@ class StockPicking(models.Model): final_seq = fields.Float(string='Remaining Time') shipping_method_so_id = fields.Many2one('delivery.carrier', string='Shipping Method SO', related='sale_id.carrier_id') state_packing = fields.Selection([('not_packing', 'Belum Packing'), ('packing_done', 'Sudah Packing')], string='Packing Status') + approval_invoice_date_id = fields.Many2one('approval.invoice.date', string='Approval Invoice Date') @api.constrains('date_doc_kirim') def _constrains_date_doc_kirim(self): for rec in self: rec.calculate_line_no() + + invoice = self.env['account.move'].search([('sale_id', '=', rec.sale_id.id)], limit=1, order='create_date desc') + + if invoice: + if rec.date_doc_kirim != invoice.invoice_date: + get_approval_invoice_date = self.env['approval.invoice.date'].search([('picking_id', '=', rec.id),('state', '=', 'draft')], limit=1) + + if get_approval_invoice_date and get_approval_invoice_date.state == 'draft': + get_approval_invoice_date.date_doc_do = rec.date_doc_kirim + else: + approval_invoice_date = self.env['approval.invoice.date'].create({ + 'picking_id': rec.id, + 'date_invoice': invoice.invoice_date, + 'date_doc_do': rec.date_doc_kirim, + 'sale_id': rec.sale_id.id, + 'move_id': invoice.id, + 'partner_id': rec.partner_id.id + }) + + rec.approval_invoice_date_id = approval_invoice_date.id + + if approval_invoice_date: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { 'title': 'Notification', 'message': 'Invoice Date Tidak Sesuai, Document Approval Invoice Date Terbuat', 'next': {'type': 'ir.actions.act_window_close'} }, + } + @api.constrains('scan_koli_lines') def _constrains_scan_koli_lines(self): @@ -1002,6 +1031,8 @@ class StockPicking(models.Model): raise UserError('Hanya MD yang bisa Approve') def button_validate(self): + self.check_invoice_date() + threshold_datetime = waktu(2025, 4, 11, 6, 26) 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') @@ -1013,7 +1044,6 @@ class StockPicking(models.Model): if self.location_id.id == 47 and self.env.user.id in users_in_group.mapped('id'): self.state_approve_md = 'done' - threshold_datetime = waktu(2025, 4, 11, 6, 26) if (len(self.konfirm_koli_lines) == 0 and 'BU/OUT/' in self.name @@ -1129,6 +1159,14 @@ class StockPicking(models.Model): self.send_mail_bills() return res + def check_invoice_date(self): + for picking in self: + invoice = self.env['account.move'].search([('sale_id', '=', picking.sale_id.id)]) + + if invoice: + if picking.date_doc_kirim.date() != invoice.invoice_date: + raise UserError("Tanggal Kirim tidak sesuai dengan Invoice") + def set_picking_code_out(self): for picking in self: # Check if picking meets criteria -- cgit v1.2.3 From d5d073f342727e8440884b462b5d3a589894f296 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 21 Apr 2025 15:28:48 +0700 Subject: validation tanggal kirim di sj --- indoteknik_custom/models/stock_picking.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 0701a989..62765099 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -250,6 +250,20 @@ class StockPicking(models.Model): state_packing = fields.Selection([('not_packing', 'Belum Packing'), ('packing_done', 'Sudah Packing')], string='Packing Status') approval_invoice_date_id = fields.Many2one('approval.invoice.date', string='Approval Invoice Date') + def _check_date_doc_kirim_modification(self): + for record in self: + if record.date_doc_kirim: + kirim_date = fields.Datetime.from_string(record.date_doc_kirim) + now = fields.Datetime.now() + + deadline = kirim_date + timedelta(days=1) + deadline = deadline.replace(hour=10, minute=0, second=0) + + if now > deadline: + raise ValidationError( + _("Anda tidak dapat mengubah Tanggal Kirim setelah jam 10:00 pada hari berikutnya!") + ) + @api.constrains('date_doc_kirim') def _constrains_date_doc_kirim(self): for rec in self: @@ -258,6 +272,7 @@ class StockPicking(models.Model): invoice = self.env['account.move'].search([('sale_id', '=', rec.sale_id.id)], limit=1, order='create_date desc') if invoice: + rec._check_date_doc_kirim_modification() if rec.date_doc_kirim != invoice.invoice_date: get_approval_invoice_date = self.env['approval.invoice.date'].search([('picking_id', '=', rec.id),('state', '=', 'draft')], limit=1) -- cgit v1.2.3 From 286d1c7d91b3e957e26a2ef1350a80faba9405ed Mon Sep 17 00:00:00 2001 From: AndriFP Date: Mon, 21 Apr 2025 15:40:54 +0700 Subject: (andrifp) fix validate NPWP format 15 digit --- indoteknik_custom/models/res_partner.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 06945301..84edafea 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -2,6 +2,7 @@ from odoo import models, fields, api from odoo.exceptions import UserError, ValidationError from datetime import datetime from odoo.http import request +import re class GroupPartner(models.Model): _name = 'group.partner' @@ -211,10 +212,24 @@ class ResPartner(models.Model): # Abaikan validasi jika NPWP kosong atau diisi "0" if not npwp or npwp == '0' or npwp == '00.000.000.0-000.000': continue - if len(npwp) < 15: - raise ValidationError("Digit NPWP yang dimasukkan kurang dari batas minimal (15 digit)") - if len(npwp) > 16: - raise ValidationError("Digit NPWP yang dimasukkan lebih dari batas maksimal (16 digit)") + + # Validasi untuk NPWP 15 digit (format: 99.999.999.9-999.999) + if len(npwp) == 20: + # Regex untuk 15 digit dengan format titik dan tanda hubung + pattern_15_digit = r'^\d{2}\.\d{3}\.\d{3}\.\d{1}-\d{3}\.\d{3}$' + if not re.match(pattern_15_digit, npwp): + raise ValidationError("Format NPWP 15 digit yang dimasukkan salah. Pastikan format yang benar adalah: 99.999.999.9-999.999") + + # Validasi untuk NPWP 16 digit (hanya angka tanpa titik atau tanda hubung) + elif len(npwp) == 16: + pattern_16_digit = r'^\d{16}$' + if not re.match(pattern_16_digit, npwp): + raise ValidationError("Format NPWP 16 digit yang dimasukkan salah. Format yang benar adalah 16 digit angka tanpa titik atau tanda hubung.") + + # Validasi panjang NPWP jika lebih atau kurang dari 15 atau 16 digit + else: + raise ValidationError("Digit NPWP yang dimasukkan tidak sesuai. Pastikan NPWP memiliki 15 digit dengan format tertentu (99.999.999.9-999.999) atau 16 digit tanpa tanda hubung.") + def write(self, vals): # Fungsi rekursif untuk meng-update semua child, termasuk child dari child -- cgit v1.2.3 From a4abe61f52162709b7e4f9f88edfc482e092c517 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 21 Apr 2025 15:41:13 +0700 Subject: validasi compare total_mapping_koli and total_scan_koli --- 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 62765099..95591c35 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -303,6 +303,9 @@ class StockPicking(models.Model): now = datetime.datetime.utcnow() for picking in self: if len(picking.scan_koli_lines) > 0: + if len(picking.scan_koli_lines) != picking.total_mapping_koli: + raise UserError("Scan Koli Tidak Sesuai Dengan Total Mapping Koli") + picking.driver_departure_date = now @api.depends('total_so_koli') -- cgit v1.2.3 From ace97e462fc9376b041ee8b45e77f55b8d4b7837 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 21 Apr 2025 16:04:22 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 95591c35..495a9d11 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1179,11 +1179,12 @@ class StockPicking(models.Model): def check_invoice_date(self): for picking in self: - invoice = self.env['account.move'].search([('sale_id', '=', picking.sale_id.id)]) + if picking.picking_type_code != 'outgoing' or 'BU/OUT/' not in picking.name: + invoice = self.env['account.move'].search([('sale_id', '=', picking.sale_id.id)]) - if invoice: - if picking.date_doc_kirim.date() != invoice.invoice_date: - raise UserError("Tanggal Kirim tidak sesuai dengan Invoice") + if invoice: + if picking.date_doc_kirim.date() != invoice.invoice_date: + raise UserError("Tanggal Kirim tidak sesuai dengan Invoice") def set_picking_code_out(self): for picking in self: -- cgit v1.2.3 From 758ce73a0f2bf8cf347d8e655954677d76349027 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 21 Apr 2025 16:10:11 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 495a9d11..977b79c0 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1180,11 +1180,26 @@ class StockPicking(models.Model): def check_invoice_date(self): for picking in self: if picking.picking_type_code != 'outgoing' or 'BU/OUT/' not in picking.name: - invoice = self.env['account.move'].search([('sale_id', '=', picking.sale_id.id)]) - - if invoice: - if picking.date_doc_kirim.date() != invoice.invoice_date: - raise UserError("Tanggal Kirim tidak sesuai dengan Invoice") + continue # Skip non-relevant pickings + + invoice = self.env['account.move'].search([('sale_id', '=', picking.sale_id.id)], limit=1) + + if not invoice: + continue # Skip if no invoice found + + # Check if both dates exist + if not picking.date_doc_kirim or not invoice.invoice_date: + raise UserError("Tanggal Kirim atau Tanggal Invoice belum diisi!") + + # Convert to date objects for comparison + picking_date = fields.Date.to_date(picking.date_doc_kirim) + invoice_date = fields.Date.to_date(invoice.invoice_date) + + if picking_date != invoice_date: + raise UserError("Tanggal Kirim (%s) tidak sesuai dengan Tanggal Invoice (%s)!" % ( + picking_date.strftime('%d-%m-%Y'), + invoice_date.strftime('%d-%m-%Y') + )) def set_picking_code_out(self): for picking in self: -- cgit v1.2.3 From b1f520b1b3b100deea99980b5781744411fe6936 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Apr 2025 09:35:32 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 977b79c0..a860dd5d 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -249,11 +249,12 @@ class StockPicking(models.Model): shipping_method_so_id = fields.Many2one('delivery.carrier', string='Shipping Method SO', related='sale_id.carrier_id') state_packing = fields.Selection([('not_packing', 'Belum Packing'), ('packing_done', 'Sudah Packing')], string='Packing Status') approval_invoice_date_id = fields.Many2one('approval.invoice.date', string='Approval Invoice Date') + last_update_date_doc_kirim = fields.Datetime(string='Last Update Tanggal Kirim') def _check_date_doc_kirim_modification(self): for record in self: - if record.date_doc_kirim: - kirim_date = fields.Datetime.from_string(record.date_doc_kirim) + if record.last_update_date_doc_kirim: + kirim_date = fields.Datetime.from_string(record.last_update_date_doc_kirim) now = fields.Datetime.now() deadline = kirim_date + timedelta(days=1) @@ -269,9 +270,9 @@ class StockPicking(models.Model): for rec in self: rec.calculate_line_no() - invoice = self.env['account.move'].search([('sale_id', '=', rec.sale_id.id)], limit=1, order='create_date desc') + invoice = self.env['account.move'].search([('sale_id', '=', rec.sale_id.id), ('move_type', '=', 'out_invoice'), ('state', '=', 'posted')], limit=1, order='create_date desc') - if invoice: + if invoice and not self.env.context.get('active_model') == 'stock.picking': rec._check_date_doc_kirim_modification() if rec.date_doc_kirim != invoice.invoice_date: get_approval_invoice_date = self.env['approval.invoice.date'].search([('picking_id', '=', rec.id),('state', '=', 'draft')], limit=1) @@ -296,6 +297,8 @@ class StockPicking(models.Model): 'tag': 'display_notification', 'params': { 'title': 'Notification', 'message': 'Invoice Date Tidak Sesuai, Document Approval Invoice Date Terbuat', 'next': {'type': 'ir.actions.act_window_close'} }, } + + rec.last_update_date_doc_kirim = fields.Datetime.now() @api.constrains('scan_koli_lines') @@ -1180,18 +1183,16 @@ class StockPicking(models.Model): def check_invoice_date(self): for picking in self: if picking.picking_type_code != 'outgoing' or 'BU/OUT/' not in picking.name: - continue # Skip non-relevant pickings + continue invoice = self.env['account.move'].search([('sale_id', '=', picking.sale_id.id)], limit=1) if not invoice: - continue # Skip if no invoice found + continue - # Check if both dates exist if not picking.date_doc_kirim or not invoice.invoice_date: raise UserError("Tanggal Kirim atau Tanggal Invoice belum diisi!") - # Convert to date objects for comparison picking_date = fields.Date.to_date(picking.date_doc_kirim) invoice_date = fields.Date.to_date(invoice.invoice_date) -- cgit v1.2.3 From 19e32a22d394e0597278ee7e1c1373d7cb799ff5 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Apr 2025 10:10:58 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 57 ++++++++++++++++--------------- 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index a860dd5d..95e0d59f 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -270,35 +270,36 @@ class StockPicking(models.Model): for rec in self: rec.calculate_line_no() - invoice = self.env['account.move'].search([('sale_id', '=', rec.sale_id.id), ('move_type', '=', 'out_invoice'), ('state', '=', 'posted')], limit=1, order='create_date desc') - - if invoice and not self.env.context.get('active_model') == 'stock.picking': - rec._check_date_doc_kirim_modification() - if rec.date_doc_kirim != invoice.invoice_date: - get_approval_invoice_date = self.env['approval.invoice.date'].search([('picking_id', '=', rec.id),('state', '=', 'draft')], limit=1) - - if get_approval_invoice_date and get_approval_invoice_date.state == 'draft': - get_approval_invoice_date.date_doc_do = rec.date_doc_kirim - else: - approval_invoice_date = self.env['approval.invoice.date'].create({ - 'picking_id': rec.id, - 'date_invoice': invoice.invoice_date, - 'date_doc_do': rec.date_doc_kirim, - 'sale_id': rec.sale_id.id, - 'move_id': invoice.id, - 'partner_id': rec.partner_id.id - }) - - rec.approval_invoice_date_id = approval_invoice_date.id - - if approval_invoice_date: - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { 'title': 'Notification', 'message': 'Invoice Date Tidak Sesuai, Document Approval Invoice Date Terbuat', 'next': {'type': 'ir.actions.act_window_close'} }, - } + if rec.picking_type_code == 'outgoing' and 'BU/OUT/' in rec.name: + invoice = self.env['account.move'].search([('sale_id', '=', rec.sale_id.id), ('move_type', '=', 'out_invoice'), ('state', '=', 'posted')], limit=1, order='create_date desc') + + if invoice and not self.env.context.get('active_model') == 'stock.picking': + rec._check_date_doc_kirim_modification() + if rec.date_doc_kirim != invoice.invoice_date: + get_approval_invoice_date = self.env['approval.invoice.date'].search([('picking_id', '=', rec.id),('state', '=', 'draft')], limit=1) + + if get_approval_invoice_date and get_approval_invoice_date.state == 'draft': + get_approval_invoice_date.date_doc_do = rec.date_doc_kirim + else: + approval_invoice_date = self.env['approval.invoice.date'].create({ + 'picking_id': rec.id, + 'date_invoice': invoice.invoice_date, + 'date_doc_do': rec.date_doc_kirim, + 'sale_id': rec.sale_id.id, + 'move_id': invoice.id, + 'partner_id': rec.partner_id.id + }) + + rec.approval_invoice_date_id = approval_invoice_date.id + + if approval_invoice_date: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { 'title': 'Notification', 'message': 'Invoice Date Tidak Sesuai, Document Approval Invoice Date Terbuat', 'next': {'type': 'ir.actions.act_window_close'} }, + } - rec.last_update_date_doc_kirim = fields.Datetime.now() + rec.last_update_date_doc_kirim = fields.Datetime.now() @api.constrains('scan_koli_lines') -- cgit v1.2.3 From fc5ed4aab391eb3ec09cae6179209fe30c1bc57f Mon Sep 17 00:00:00 2001 From: AndriFP Date: Tue, 22 Apr 2025 10:57:24 +0700 Subject: (andri) add min amount vendor payment --- indoteknik_custom/models/purchase_order.py | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index b107f389..5e9e509f 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -89,6 +89,39 @@ class PurchaseOrder(models.Model): store_name = fields.Char(string='Nama Toko') purchase_order_count = fields.Integer('Purchase Order Count', related='partner_id.purchase_order_count') + # cek payment term + def _check_payment_term(self): + _logger.info("Check Payment Term Terpanggil") + + cbd_term = self.env['account.payment.term'].search([ + ('name', 'ilike', 'Cash Before Delivery') + ], limit=1) + + for order in self: + if not order.partner_id or not order.partner_id.minimum_amount: + continue + + if not order.order_line or order.amount_total == 0: + continue + + if order.amount_total < order.partner_id.minimum_amount: + if cbd_term and order.payment_term_id != cbd_term: + order.payment_term_id = cbd_term.id + self.env.user.notify_info( + message="Total belanja PO belum mencapai minimum yang ditentukan vendor. " + "Payment Term telah otomatis diubah menjadi Cash Before Delivery (C.B.D).", + title="Payment Term Diperbarui" + ) + else: + vendor_term = order.partner_id.property_supplier_payment_term_id + if vendor_term and order.payment_term_id != vendor_term: + order.payment_term_id = vendor_term.id + self.env.user.notify_info( + message=f"Total belanja PO telah memenuhi jumlah minimum vendor. " + f"Payment Term otomatis dikembalikan ke pengaturan vendor awal: *{vendor_term.name}*.", + title="Payment Term Diperbarui" + ) + @api.onchange('total_cost_service') def _onchange_total_cost_service(self): for order in self: @@ -672,6 +705,7 @@ class PurchaseOrder(models.Model): raise UserError("Produk "+line.product_id.name+" memiliki vendor berbeda dengan SO (Vendor PO: "+str(self.partner_id.name)+", Vendor SO: "+str(line.so_line_id.vendor_id.name)+")") def button_confirm(self): + # self._check_payment_term() # check payment term res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() self.check_ppn_mix() @@ -1079,6 +1113,17 @@ class PurchaseOrder(models.Model): return super(PurchaseOrder, self).button_unlock() + @api.model #override custom create & write for check payment term + def create(self, vals): + order = super().create(vals) + order.with_context(skip_check_payment=True)._check_payment_term() + return order + + def write(self, vals): + res = super().write(vals) + if not self.env.context.get('skip_check_payment'): + self.with_context(skip_check_payment=True)._check_payment_term() + return res class PurchaseOrderUnlockWizard(models.TransientModel): _name = 'purchase.order.unlock.wizard' -- cgit v1.2.3 From bdf8bf07485b01e26f61cbc75578d754af4439e8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Apr 2025 11:58:44 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 95e0d59f..96aac7a1 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -270,7 +270,7 @@ class StockPicking(models.Model): for rec in self: rec.calculate_line_no() - if rec.picking_type_code == 'outgoing' and 'BU/OUT/' in rec.name: + if rec.picking_type_code == 'outgoing' and 'BU/OUT/' in rec.name and rec.partner_id.id != 96868: invoice = self.env['account.move'].search([('sale_id', '=', rec.sale_id.id), ('move_type', '=', 'out_invoice'), ('state', '=', 'posted')], limit=1, order='create_date desc') if invoice and not self.env.context.get('active_model') == 'stock.picking': @@ -299,7 +299,7 @@ class StockPicking(models.Model): 'params': { 'title': 'Notification', 'message': 'Invoice Date Tidak Sesuai, Document Approval Invoice Date Terbuat', 'next': {'type': 'ir.actions.act_window_close'} }, } - rec.last_update_date_doc_kirim = fields.Datetime.now() + rec.last_update_date_doc_kirim = datetime.datetime.utcnow() @api.constrains('scan_koli_lines') @@ -1183,7 +1183,7 @@ class StockPicking(models.Model): def check_invoice_date(self): for picking in self: - if picking.picking_type_code != 'outgoing' or 'BU/OUT/' not in picking.name: + if picking.picking_type_code != 'outgoing' or 'BU/OUT/' not in picking.name or picking.partner_id.id == 96868: continue invoice = self.env['account.move'].search([('sale_id', '=', picking.sale_id.id)], limit=1) -- cgit v1.2.3 From 2f16e84dcceec98e3dd49cbbbf57457d00989a04 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Tue, 22 Apr 2025 12:28:04 +0700 Subject: (miqdad) add xpdc --- indoteknik_custom/models/sale_order.py | 79 +++++++++++++--------------------- 1 file changed, 29 insertions(+), 50 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 92581678..2061c686 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -67,6 +67,17 @@ class ShippingOption(models.Model): class SaleOrder(models.Model): _inherit = "sale.order" + ongkir_ke_xpdc = fields.Float(string='Ongkir ke Ekspedisi', help='Biaya ongkir ekspedisi', copy=False, index=True, tracking=3) + + metode_kirim_ke_xpdc = fields.Selection([ + ('indoteknik_deliv', 'Indoteknik Delivery'), + ('lalamove', 'Lalamove'), + ('grab', 'Grab'), + ('gojek', 'Gojek'), + ('deliveree', 'Deliveree'), + ('other', 'Other'), + ], string='Metode Kirim Ke Ekspedisi', copy=False, index=True, tracking=3) + koli_lines = fields.One2many('sales.order.koli', 'sale_order_id', string='Sales Order Koli', auto_join=True) fulfillment_line_v2 = fields.One2many('sales.order.fulfillment.v2', 'sale_order_id', string='Fullfillment2') fullfillment_line = fields.One2many('sales.order.fullfillment', 'sales_order_id', string='Fullfillment') @@ -315,17 +326,7 @@ class SaleOrder(models.Model): "sale_order_id": self.id, }) self.shipping_option_id = shipping_option.id - self.message_post( - body=( - f"Estimasi pengiriman Indoteknik berhasil:
" - f"Layanan: {shipping_option.name}
" - f"ETD: {shipping_option.etd}
" - f"Biaya: Rp {shipping_option.price:,}
" - f"Provider: {shipping_option.provider}" - ), - message_type="comment", - ) - + def action_estimate_shipping(self): if self.carrier_id.id in [1, 151]: self.action_indoteknik_estimate_shipping() @@ -364,8 +365,6 @@ class SaleOrder(models.Model): shipping_options.append((service, description, etd, value, courier['code'])) self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() - - _logger.info(f"Shipping options: {shipping_options}") for service, description, etd, value, provider in shipping_options: self.env["shipping.option"].create({ @@ -375,23 +374,12 @@ class SaleOrder(models.Model): "etd": etd, "sale_order_id": self.id, }) - self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id - _logger.info(f"Shipping option SO ID: {self.shipping_option_id}") - - self.message_post( - body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
" - f"{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}", - message_type="comment" - ) - - # self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}", message_type="comment") - + self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
Detail Lain:
{'
'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}") else: raise UserError("Gagal mendapatkan estimasi ongkir.") - def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id): url = 'https://pro.rajaongkir.com/api/cost' @@ -495,7 +483,7 @@ class SaleOrder(models.Model): def _compute_date_kirim(self): for rec in self: - picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel'])], order='date_doc_kirim desc', limit=1) + picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel']), ('name', 'not ilike', 'BU/PICK/%')], order='date_doc_kirim desc', limit=1) rec.date_kirim_ril = picking.date_doc_kirim rec.date_status_done = picking.date_done rec.date_driver_arrival = picking.driver_arrival_date @@ -694,30 +682,12 @@ class SaleOrder(models.Model): # @api.constrains('delivery_amt', 'carrier_id', 'shipping_cost_covered') def _validate_delivery_amt(self): - is_indoteknik = self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik' - is_active_id = not self.env.context.get('active_id', []) - - if is_indoteknik and is_active_id: - if self.delivery_amt == 0: - if self.carrier_id.id == 1: - raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum diisi.') - else: - raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum diisi.') - - if self.delivery_amt < 5000: - if self.carrier_id.id == 1: - raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi tarif minimum.') + if self.delivery_amt < 1: + if(self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): + if(self.carrier_id.id == 1): + raise UserError('Untuk Kurir Indoteknik Delivery, Estimasi Ongkos Kirim Harus di isi') else: - raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi tarif minimum.') - - - # if self.delivery_amt < 5000: - # if (self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): - # if self.carrier_id.id == 1: - # raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi jumlah minimum.') - # else: - # raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi jumlah minimum.') - + raise UserError('Untuk Shipping Covered Indoteknik, Estimasi Ongkos Kirim Harus di isi') def override_allow_create_invoice(self): if not self.env.user.is_accounting: @@ -1467,12 +1437,21 @@ class SaleOrder(models.Model): # partner.npwp = self.npwp # partner.sppkp = self.sppkp # partner.email = self.email - + def _compute_total_margin(self): for order in self: total_margin = sum(line.item_margin for line in order.order_line if line.product_id) + #hitung nek onk + if order.ongkir_ke_xpdc: + total_margin -= order.ongkir_ke_xpdc + order.total_margin = total_margin + # def _compute_total_margin(self): + # for order in self: + # total_margin = sum(line.item_margin for line in order.order_line if line.product_id) + # order.total_margin = total_margin + def _compute_total_percent_margin(self): for order in self: if order.amount_untaxed == 0: -- cgit v1.2.3 From 71e47cc88e250600c2975a114dd420f27fda36b3 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Tue, 22 Apr 2025 12:45:44 +0700 Subject: (andri) change min dev amt from 5000 to 100 --- 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 92581678..37f767ec 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -704,7 +704,7 @@ class SaleOrder(models.Model): else: raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum diisi.') - if self.delivery_amt < 5000: + if self.delivery_amt < 100: if self.carrier_id.id == 1: raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi tarif minimum.') else: -- cgit v1.2.3 From 9e867f016484f8695fce9e0c313d41010434390c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 22 Apr 2025 15:01:28 +0700 Subject: push --- indoteknik_custom/models/stock_picking.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 96aac7a1..cd038f44 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -26,11 +26,11 @@ _biteship_api_key = "biteship_test.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1l class StockPicking(models.Model): _inherit = 'stock.picking' _order = 'final_seq ASC' - konfirm_koli_lines = fields.One2many('konfirm.koli', 'picking_id', string='Konfirm Koli', auto_join=True) - scan_koli_lines = fields.One2many('scan.koli', 'picking_id', string='Scan Koli', auto_join=True) - check_koli_lines = fields.One2many('check.koli', 'picking_id', string='Check Koli', auto_join=True) + konfirm_koli_lines = fields.One2many('konfirm.koli', 'picking_id', string='Konfirm Koli', auto_join=True, copy=False) + scan_koli_lines = fields.One2many('scan.koli', 'picking_id', string='Scan Koli', auto_join=True, copy=False) + check_koli_lines = fields.One2many('check.koli', 'picking_id', string='Check Koli', auto_join=True, copy=False) - check_product_lines = fields.One2many('check.product', 'picking_id', string='Check Product', auto_join=True) + check_product_lines = fields.One2many('check.product', 'picking_id', string='Check Product', auto_join=True, copy=False) barcode_product_lines = fields.One2many('barcode.product', 'picking_id', string='Barcode Product', auto_join=True) is_internal_use = fields.Boolean('Internal Use', help='flag which is internal use or not') account_id = fields.Many2one('account.account', string='Account') @@ -100,7 +100,7 @@ class StockPicking(models.Model): ('pengajuan1', 'Approval Finance'), ('approved', 'Approved'), ], string='Approval Return Status', readonly=True, copy=False, index=True, tracking=3, help="Approval Status untuk Return") - date_doc_kirim = fields.Datetime(string='Tanggal Kirim di SJ', help="Tanggal Kirim di cetakan SJ, tidak berpengaruh ke Accounting", tracking=True) + date_doc_kirim = fields.Datetime(string='Tanggal Kirim di SJ', help="Tanggal Kirim di cetakan SJ, tidak berpengaruh ke Accounting", tracking=True, copy=False) note_logistic = fields.Selection([ ('hold', 'Hold by Sales'), ('not_paid', 'Customer belum bayar'), @@ -154,8 +154,8 @@ class StockPicking(models.Model): # record.show_state_approve_md = record.location_id.id == 47 or record.location_id.complete_name == "Virtual Locations/Gudang Selisih" quantity_koli = fields.Float(string="Quantity Koli", copy=False) total_mapping_koli = fields.Float(string="Total Mapping Koli", compute='_compute_total_mapping_koli') - so_lama = fields.Boolean('SO LAMA') - linked_manual_bu_out = fields.Many2one('stock.picking', string='BU Out') + so_lama = fields.Boolean('SO LAMA', copy=False) + linked_manual_bu_out = fields.Many2one('stock.picking', string='BU Out', copy=False) # def write(self, vals): # if 'linked_manual_bu_out' in vals: -- cgit v1.2.3 From 30382037882e15bb43f56fc0d81500faeb364fa5 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 23 Apr 2025 08:59:23 +0700 Subject: (andri) add field min amt tax vendor PO --- indoteknik_custom/models/purchase_order.py | 76 ++++++++++++++++++++++++++++++ indoteknik_custom/models/res_partner.py | 4 ++ 2 files changed, 80 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 5e9e509f..60d26105 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -122,6 +122,80 @@ class PurchaseOrder(models.Model): title="Payment Term Diperbarui" ) + def _check_tax_rule(self): + _logger.info("Check Tax Rule Terpanggil") + + # Pajak 11% + tax_11 = self.env['account.tax'].search([ + ('type_tax_use', '=', 'purchase'), + ('name', 'ilike', '11%') + ], limit=1) + + # Pajak "No Tax" + no_tax = self.env['account.tax'].search([ + ('type_tax_use', '=', 'purchase'), + ('name', 'ilike', 'no tax') + ], limit=1) + + if not tax_11: + raise UserError("Pajak 11% tidak ditemukan. Mohon pastikan pajak 11% tersedia.") + + if not no_tax: + raise UserError("Pajak 'No Tax' tidak ditemukan. Harap buat tax dengan nama 'No Tax' dan tipe 'Purchase'.") + + for order in self: + partner = order.partner_id + minimum_tax = partner.minimum_amount_tax + + _logger.info("Partner ID: %s, Minimum Tax: %s, Untaxed Total: %s", partner.id, minimum_tax, order.amount_untaxed) + + if not minimum_tax or not order.order_line: + continue + + if order.amount_untaxed < minimum_tax: + _logger.info(">>> Total di bawah minimum → apply No Tax") + for line in order.order_line: + line.taxes_id = [(6, 0, [no_tax.id])] + + if self.env.context.get('notify_tax'): + self.env.user.notify_info( + message="Total belanja PO belum mencapai minimum pajak vendor. " + "Pajak diganti menjadi 'No Tax'.", + title="Pajak Diperbarui", + sticky=True + ) + else: + _logger.info(">>> Total memenuhi minimum → apply Pajak 11%") + for line in order.order_line: + line.taxes_id = [(6, 0, [tax_11.id])] + + if self.env.context.get('notify_tax'): + self.env.user.notify_info( + message="Total belanja sebelum pajak telah memenuhi minimum. " + "Pajak 11%% diterapkan", + title="Pajak Diperbarui", + sticky=True + ) + + @api.onchange('order_line') + def _onchange_order_line_tax_default(self): + _logger.info("Onchange Order Line Tax Default Terpanggil") + + no_tax = self.env['account.tax'].search([ + ('type_tax_use', '=', 'purchase'), + ('name', 'ilike', 'no tax') + ], limit=1) + + if not no_tax: + _logger.info("No Tax tidak ditemukan") + return + + for order in self: + for line in order.order_line: + if not line.taxes_id: + line.taxes_id = [(6, 0, [no_tax.id])] + _logger.info("Auto-set No tax ke baris product: %s", line.product_id.name) + @api.onchange('total_cost_service') def _onchange_total_cost_service(self): for order in self: @@ -1117,12 +1191,14 @@ class PurchaseOrder(models.Model): def create(self, vals): order = super().create(vals) order.with_context(skip_check_payment=True)._check_payment_term() + order.with_context(notify_tax=True)._check_tax_rule() return order def write(self, vals): res = super().write(vals) if not self.env.context.get('skip_check_payment'): self.with_context(skip_check_payment=True)._check_payment_term() + self.with_context(notify_tax=True)._check_tax_rule() return res class PurchaseOrderUnlockWizard(models.TransientModel): diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 84edafea..191a44c9 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -44,6 +44,10 @@ class ResPartner(models.Model): string="Minimum Order", help="Jika total belanja kurang dari ini, maka payment term akan otomatis menjadi CBD." ) + minimum_amount_tax = fields.Float( + string="Minimum Amount Tax", + help="Jika total belanja kurang dari ini, maka tax akan otomatis menjadi 0%." + ) category_produk_ids = fields.Many2many('product.public.category', string='Kategori Produk yang Digunakan', domain=lambda self: self._get_default_category_domain()) @api.model -- cgit v1.2.3 From 8334445b2946fc7383acb682ec5cde3598b8accc Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 23 Apr 2025 09:01:21 +0700 Subject: (miqdad) fix duplicate voucher --- indoteknik_custom/models/voucher.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index 101d4bcf..7b458d01 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -265,3 +265,19 @@ class Voucher(models.Model): tnc.append(f'
  • {line_tnc}
  • ') return ' '.join(tnc) + # copy semua data kalau diduplicate + def copy(self, default=None): + default = dict(default or {}) + voucher_lines = [] + + for line in self.voucher_line: + voucher_lines.append((0, 0, { + 'manufacture_id': line.manufacture_id.id, + 'discount_amount': line.discount_amount, + 'discount_type': line.discount_type, + 'min_purchase_amount': line.min_purchase_amount, + 'max_discount_amount': line.max_discount_amount, + })) + + default['voucher_line'] = voucher_lines + return super(Voucher, self).copy(default) \ No newline at end of file -- cgit v1.2.3 From f3854677b0f74db2fbb54ad012b3a6a6fc9e11df Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 23 Apr 2025 11:53:12 +0700 Subject: (andri) fix notify ganda pada PO --- indoteknik_custom/models/purchase_order.py | 39 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 60d26105..98b367d0 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -152,7 +152,7 @@ class PurchaseOrder(models.Model): if not minimum_tax or not order.order_line: continue - if order.amount_untaxed < minimum_tax: + if order.amount_total < minimum_tax: _logger.info(">>> Total di bawah minimum → apply No Tax") for line in order.order_line: line.taxes_id = [(6, 0, [no_tax.id])] @@ -162,7 +162,6 @@ class PurchaseOrder(models.Model): message="Total belanja PO belum mencapai minimum pajak vendor. " "Pajak diganti menjadi 'No Tax'.", title="Pajak Diperbarui", - sticky=True ) else: _logger.info(">>> Total memenuhi minimum → apply Pajak 11%") @@ -174,27 +173,27 @@ class PurchaseOrder(models.Model): message="Total belanja sebelum pajak telah memenuhi minimum. " "Pajak 11%% diterapkan", title="Pajak Diperbarui", - sticky=True ) - @api.onchange('order_line') - def _onchange_order_line_tax_default(self): - _logger.info("Onchange Order Line Tax Default Terpanggil") + # set default no_tax pada order line + # @api.onchange('order_line') + # def _onchange_order_line_tax_default(self): + # _logger.info("Onchange Order Line Tax Default Terpanggil") - no_tax = self.env['account.tax'].search([ - ('type_tax_use', '=', 'purchase'), - ('name', 'ilike', 'no tax') - ], limit=1) + # no_tax = self.env['account.tax'].search([ + # ('type_tax_use', '=', 'purchase'), + # ('name', 'ilike', 'no tax') + # ], limit=1) - if not no_tax: - _logger.info("No Tax tidak ditemukan") - return + # if not no_tax: + # _logger.info("No Tax tidak ditemukan") + # return - for order in self: - for line in order.order_line: - if not line.taxes_id: - line.taxes_id = [(6, 0, [no_tax.id])] - _logger.info("Auto-set No tax ke baris product: %s", line.product_id.name) + # for order in self: + # for line in order.order_line: + # if not line.taxes_id: + # line.taxes_id = [(6, 0, [no_tax.id])] + # _logger.info("Auto-set No tax ke baris product: %s", line.product_id.name) @api.onchange('total_cost_service') def _onchange_total_cost_service(self): @@ -1190,8 +1189,8 @@ class PurchaseOrder(models.Model): @api.model #override custom create & write for check payment term def create(self, vals): order = super().create(vals) - order.with_context(skip_check_payment=True)._check_payment_term() - order.with_context(notify_tax=True)._check_tax_rule() + # order.with_context(skip_check_payment=True)._check_payment_term() + # order.with_context(notify_tax=True)._check_tax_rule() return order def write(self, vals): -- cgit v1.2.3 From 1981b2d576d916374c181c8089655ab59a3f7f20 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 23 Apr 2025 14:29:06 +0700 Subject: barcode box --- indoteknik_custom/models/barcoding_product.py | 11 ++++-- indoteknik_custom/models/product_template.py | 2 ++ indoteknik_custom/models/stock_picking.py | 49 ++++++++++++++++++++------- 3 files changed, 46 insertions(+), 16 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/barcoding_product.py b/indoteknik_custom/models/barcoding_product.py index e1b8f41f..17057d1d 100644 --- a/indoteknik_custom/models/barcoding_product.py +++ b/indoteknik_custom/models/barcoding_product.py @@ -12,15 +12,20 @@ class BarcodingProduct(models.Model): barcoding_product_line = fields.One2many('barcoding.product.line', 'barcoding_product_id', string='Barcoding Product Lines', auto_join=True) product_id = fields.Many2one('product.product', string="Product", tracking=3) quantity = fields.Float(string="Quantity", tracking=3) - type = fields.Selection([('print', 'Print Barcode'), ('barcoding', 'Add Barcode To Product')], string='Type', default='print') + type = fields.Selection([('print', 'Print Barcode'), ('barcoding', 'Add Barcode To Product'), ('barcoding_box', 'Add Barcode Box To Product')], string='Type', default='print') barcode = fields.Char(string="Barcode") + qty_pcs_box = fields.Char(string="Quantity Pcs Box") @api.constrains('barcode') def _send_barcode_to_product(self): for record in self: if record.barcode and not record.product_id.barcode: - record.product_id.barcode = record.barcode - + if record.type == 'barcoding_box': + record.product_id.barcode_box = record.barcode + record.product_id.qty_pcs_box = record.qty_pcs_box + else: + record.product_id.barcode = record.barcode + @api.onchange('product_id', 'quantity') def _onchange_product_or_quantity(self): """Update barcoding_product_line based on product_id and quantity""" diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 600dd90e..e6a01a04 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -421,6 +421,8 @@ class ProductProduct(models.Model): plafon_qty = fields.Float(string='Max Plafon', compute='_get_plafon_qty_product') merchandise_ok = fields.Boolean(string='Product Promotion') qr_code_variant = fields.Binary("QR Code Variant", compute='_compute_qr_code_variant') + qty_pcs_box = fields.Float("Pcs Box") + barcode_box = fields.Char("Barcode Box") def generate_product_sla(self): product_variant_ids = self.env.context.get('active_ids', []) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index cd038f44..6168d3b2 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1621,21 +1621,44 @@ class CheckProduct(models.Model): copy=False, ) product_id = fields.Many2one('product.product', string='Product') - quantity = fields.Float(string='Quantity', default=1.0) + quantity = fields.Float(string='Quantity') status = fields.Char(string='Status', compute='_compute_status') code_product = fields.Char(string='Code Product') @api.onchange('code_product') def _onchange_code_product(self): - if self.code_product: - product = self.env['product.product'].search([('default_code', '=', self.code_product)], limit=1) - if not product: - product = self.env['product.product'].search([('barcode', '=', self.code_product)], limit=1) - - if product: - self.product_id = product.id - else: - raise UserError("Product tidak ditemukan") + if not self.code_product: + return + + # Cari product berdasarkan default_code, barcode, atau barcode_box + product = self.env['product.product'].search([ + '|', + ('default_code', '=', self.code_product), + '|', + ('barcode', '=', self.code_product), + ('barcode_box', '=', self.code_product) + ], limit=1) + + if not product: + raise UserError("Product tidak ditemukan") + + # Jika scan barcode_box, set quantity sesuai qty_pcs_box + if product.barcode_box == self.code_product: + self.product_id = product.id + self.quantity = product.qty_pcs_box + self.code_product = product.default_code or product.barcode + # return { + # 'warning': { + # 'title': 'Info',8994175025871 + + # 'message': f'Product box terdeteksi. Quantity di-set ke {product.qty_pcs_box}' + # } + # } + else: + # Jika scan biasa + self.product_id = product.id + self.code_product = product.default_code or product.barcode + self.quantity = 1 def unlink(self): # Get all affected pickings before deletion @@ -1763,7 +1786,7 @@ class CheckProduct(models.Model): # Find existing lines for the same product, excluding the current line existing_lines = record.picking_id.check_product_lines.filtered( - lambda line: line.product_id == record.product_id and line.id != record.id + lambda line: line.product_id == record.product_id ) if existing_lines: @@ -1771,9 +1794,9 @@ class CheckProduct(models.Model): first_line = existing_lines[0] # Calculate the total quantity after addition - total_quantity = sum(existing_lines.mapped('quantity')) - record.quantity + total_quantity = sum(existing_lines.mapped('quantity')) - if total_quantity == total_qty_in_moves: + if total_quantity > total_qty_in_moves: raise UserError(( "Quantity Product '%s' sudah melebihi quantity demand." ) % (record.product_id.display_name)) -- cgit v1.2.3 From 3f0a246d364a07f8c61eafeefcee7b37232a5933 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 23 Apr 2025 14:57:14 +0700 Subject: (miqdad) rev add xpdc --- indoteknik_custom/models/sale_order.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 2061c686..bdb79fdf 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1438,19 +1438,6 @@ class SaleOrder(models.Model): # partner.sppkp = self.sppkp # partner.email = self.email - def _compute_total_margin(self): - for order in self: - total_margin = sum(line.item_margin for line in order.order_line if line.product_id) - #hitung nek onk - if order.ongkir_ke_xpdc: - total_margin -= order.ongkir_ke_xpdc - - order.total_margin = total_margin - - # def _compute_total_margin(self): - # for order in self: - # total_margin = sum(line.item_margin for line in order.order_line if line.product_id) - # order.total_margin = total_margin def _compute_total_percent_margin(self): for order in self: @@ -1768,4 +1755,13 @@ class SaleOrder(models.Model): self._validate_delivery_amt() if any(field in vals for field in ["order_line", "client_order_ref"]): self._calculate_etrts_date() - return res \ No newline at end of file + return res + + def _compute_total_margin(self): + for order in self: + total_margin = sum(line.item_margin for line in order.order_line if line.product_id) + #hitung nek onk + if order.ongkir_ke_xpdc: + total_margin -= order.ongkir_ke_xpdc + + order.total_margin = total_margin \ No newline at end of file -- cgit v1.2.3 From f710d62fcb33e43a832d18b28baa4641f9fb65a8 Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 23 Apr 2025 15:39:46 +0700 Subject: (miqdad) Fix conflict Xpdc --- indoteknik_custom/models/sale_order.py | 76 ++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 18 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index bdb79fdf..6b603146 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -326,7 +326,17 @@ class SaleOrder(models.Model): "sale_order_id": self.id, }) self.shipping_option_id = shipping_option.id - + self.message_post( + body=( + f"Estimasi pengiriman Indoteknik berhasil:
    " + f"Layanan: {shipping_option.name}
    " + f"ETD: {shipping_option.etd}
    " + f"Biaya: Rp {shipping_option.price:,}
    " + f"Provider: {shipping_option.provider}" + ), + message_type="comment", + ) + def action_estimate_shipping(self): if self.carrier_id.id in [1, 151]: self.action_indoteknik_estimate_shipping() @@ -365,6 +375,8 @@ class SaleOrder(models.Model): shipping_options.append((service, description, etd, value, courier['code'])) self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink() + + _logger.info(f"Shipping options: {shipping_options}") for service, description, etd, value, provider in shipping_options: self.env["shipping.option"].create({ @@ -374,12 +386,23 @@ class SaleOrder(models.Model): "etd": etd, "sale_order_id": self.id, }) + self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id - self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
    Detail Lain:
    {'
    '.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}") + _logger.info(f"Shipping option SO ID: {self.shipping_option_id}") + + self.message_post( + body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
    Detail Lain:
    " + f"{'
    '.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}", + message_type="comment" + ) + + # self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}
    Detail Lain:
    {'
    '.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}", message_type="comment") + else: raise UserError("Gagal mendapatkan estimasi ongkir.") + def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id): url = 'https://pro.rajaongkir.com/api/cost' @@ -483,7 +506,7 @@ class SaleOrder(models.Model): def _compute_date_kirim(self): for rec in self: - picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel']), ('name', 'not ilike', 'BU/PICK/%')], order='date_doc_kirim desc', limit=1) + picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel'])], order='date_doc_kirim desc', limit=1) rec.date_kirim_ril = picking.date_doc_kirim rec.date_status_done = picking.date_done rec.date_driver_arrival = picking.driver_arrival_date @@ -682,12 +705,30 @@ class SaleOrder(models.Model): # @api.constrains('delivery_amt', 'carrier_id', 'shipping_cost_covered') def _validate_delivery_amt(self): - if self.delivery_amt < 1: - if(self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): - if(self.carrier_id.id == 1): - raise UserError('Untuk Kurir Indoteknik Delivery, Estimasi Ongkos Kirim Harus di isi') + is_indoteknik = self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik' + is_active_id = not self.env.context.get('active_id', []) + + if is_indoteknik and is_active_id: + if self.delivery_amt == 0: + if self.carrier_id.id == 1: + raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum diisi.') + else: + raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum diisi.') + + if self.delivery_amt < 100: + if self.carrier_id.id == 1: + raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi tarif minimum.') else: - raise UserError('Untuk Shipping Covered Indoteknik, Estimasi Ongkos Kirim Harus di isi') + raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi tarif minimum.') + + + # if self.delivery_amt < 5000: + # if (self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []): + # if self.carrier_id.id == 1: + # raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi jumlah minimum.') + # else: + # raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi jumlah minimum.') + def override_allow_create_invoice(self): if not self.env.user.is_accounting: @@ -1437,7 +1478,15 @@ class SaleOrder(models.Model): # partner.npwp = self.npwp # partner.sppkp = self.sppkp # partner.email = self.email + + def _compute_total_margin(self): + for order in self: + total_margin = sum(line.item_margin for line in order.order_line if line.product_id) + #hitung nek onk + if order.ongkir_ke_xpdc: + total_margin -= order.ongkir_ke_xpdc + order.total_margin = total_margin def _compute_total_percent_margin(self): for order in self: @@ -1755,13 +1804,4 @@ class SaleOrder(models.Model): self._validate_delivery_amt() if any(field in vals for field in ["order_line", "client_order_ref"]): self._calculate_etrts_date() - return res - - def _compute_total_margin(self): - for order in self: - total_margin = sum(line.item_margin for line in order.order_line if line.product_id) - #hitung nek onk - if order.ongkir_ke_xpdc: - total_margin -= order.ongkir_ke_xpdc - - order.total_margin = total_margin \ No newline at end of file + return res \ No newline at end of file -- cgit v1.2.3 From 5f78d57ced0957b5f05e590de67a4b966b22e85b Mon Sep 17 00:00:00 2001 From: AndriFP Date: Wed, 23 Apr 2025 15:46:28 +0700 Subject: (miqdad) fix conflict Xpdc --- indoteknik_custom/models/sale_order.py | 1 - 1 file changed, 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 6b603146..13646847 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1482,7 +1482,6 @@ class SaleOrder(models.Model): def _compute_total_margin(self): for order in self: total_margin = sum(line.item_margin for line in order.order_line if line.product_id) - #hitung nek onk if order.ongkir_ke_xpdc: total_margin -= order.ongkir_ke_xpdc -- cgit v1.2.3 From beb2ef24d462075dc390018afe1127db313fb404 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 24 Apr 2025 10:39:19 +0700 Subject: push --- indoteknik_custom/models/barcoding_product.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/barcoding_product.py b/indoteknik_custom/models/barcoding_product.py index 17057d1d..353f94d5 100644 --- a/indoteknik_custom/models/barcoding_product.py +++ b/indoteknik_custom/models/barcoding_product.py @@ -19,12 +19,11 @@ class BarcodingProduct(models.Model): @api.constrains('barcode') def _send_barcode_to_product(self): for record in self: - if record.barcode and not record.product_id.barcode: - if record.type == 'barcoding_box': - record.product_id.barcode_box = record.barcode - record.product_id.qty_pcs_box = record.qty_pcs_box - else: - record.product_id.barcode = record.barcode + if record.type == 'barcoding_box': + record.product_id.barcode_box = record.barcode + record.product_id.qty_pcs_box = record.qty_pcs_box + else: + record.product_id.barcode = record.barcode @api.onchange('product_id', 'quantity') def _onchange_product_or_quantity(self): -- cgit v1.2.3 From 4706b80d3d3b1e55c198d2b4cfb93f7fa47c9732 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 24 Apr 2025 13:49:35 +0700 Subject: validation duplicate barcode product and barcode box, cr date doc kirim, validation duplicate product id on so line --- indoteknik_custom/models/approval_date_doc.py | 9 ++++++--- indoteknik_custom/models/barcoding_product.py | 13 +++++++++++++ indoteknik_custom/models/sale_order.py | 10 ++++++++++ indoteknik_custom/models/stock_picking.py | 12 ++++++------ 4 files changed, 35 insertions(+), 9 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/approval_date_doc.py b/indoteknik_custom/models/approval_date_doc.py index 751bae82..1a2749d5 100644 --- a/indoteknik_custom/models/approval_date_doc.py +++ b/indoteknik_custom/models/approval_date_doc.py @@ -39,12 +39,15 @@ class ApprovalDateDoc(models.Model): if not self.env.user.is_accounting: raise UserError("Hanya Accounting Yang Bisa Approve") self.check_invoice_so_picking - self.picking_id.driver_departure_date = self.driver_departure_date - self.picking_id.date_doc_kirim = self.driver_departure_date + # Tambahkan context saat mengupdate date_doc_kirim + self.picking_id.with_context(from_button_approve=True).write({ + 'driver_departure_date': self.driver_departure_date, + 'date_doc_kirim': self.driver_departure_date + }) self.state = 'done' self.approve_date = datetime.utcnow() self.approve_by = self.env.user.id - + def button_cancel(self): self.state = 'cancel' diff --git a/indoteknik_custom/models/barcoding_product.py b/indoteknik_custom/models/barcoding_product.py index 353f94d5..e28473ff 100644 --- a/indoteknik_custom/models/barcoding_product.py +++ b/indoteknik_custom/models/barcoding_product.py @@ -16,9 +16,22 @@ class BarcodingProduct(models.Model): barcode = fields.Char(string="Barcode") qty_pcs_box = fields.Char(string="Quantity Pcs Box") + def check_duplicate_barcode(self): + barcode_product = self.env['product.product'].search([('barcode', '=', self.barcode)]) + + if barcode_product: + raise UserError('Barcode sudah digunakan {}'.format(barcode_product.display_name)) + + barcode_box = self.env['product.product'].search([('barcode_box', '=', self.barcode)]) + + if barcode_box: + raise UserError('Barcode box sudah digunakan {}'.format(barcode_box.display_name)) + + @api.constrains('barcode') def _send_barcode_to_product(self): for record in self: + record.check_duplicate_barcode() if record.type == 'barcoding_box': record.product_id.barcode_box = record.barcode record.product_id.qty_pcs_box = record.qty_pcs_box diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 39d6fd0b..02d61387 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1069,7 +1069,16 @@ class SaleOrder(models.Model): raise UserError("Product BOM belum dikonfirmasi di Manufacturing Orders. Silakan hubungi MD.") else: raise UserError("Product BOM tidak di temukan di manufacturing orders, silahkan hubungi MD") + + def check_duplicate_product(self): + for order in self: + for line in order.order_line: + search_product = self.env['sale.order.line'].search([('product_id', '=', line.product_id.id), ('order_id', '=', order.id)]) + if len(search_product) > 1: + raise UserError("Terdapat DUPLIKASI data pada Product {}".format(line.product_id.display_name)) + def sale_order_approve(self): + self.check_duplicate_product() self.check_product_bom() self.check_credit_limit() self.check_limit_so_to_invoice() @@ -1310,6 +1319,7 @@ class SaleOrder(models.Model): def action_confirm(self): for order in self: + order.check_duplicate_product() order.check_product_bom() order.check_credit_limit() order.check_limit_so_to_invoice() diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 6168d3b2..f812df86 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -102,10 +102,9 @@ class StockPicking(models.Model): ], string='Approval Return Status', readonly=True, copy=False, index=True, tracking=3, help="Approval Status untuk Return") date_doc_kirim = fields.Datetime(string='Tanggal Kirim di SJ', help="Tanggal Kirim di cetakan SJ, tidak berpengaruh ke Accounting", tracking=True, copy=False) note_logistic = fields.Selection([ - ('hold', 'Hold by Sales'), + ('wait_so_together', 'Tunggu SO Barengan'), ('not_paid', 'Customer belum bayar'), - ('partial', 'Kirim Parsial'), - ('indent', 'Indent'), + ('reserve_stock', 'Reserve Stock'), ('waiting_schedule', 'Menunggu Jadwal Kirim'), ('self_pickup', 'Barang belum di pickup Customer'), ('expedition_closed', 'Eskpedisi belum buka') @@ -141,7 +140,8 @@ class StockPicking(models.Model): ('done', 'Done'), ('cancel', 'Cancelled'), ], string='Status Reserve', tracking=True, copy=False, help="The current state of the stock picking.") - notee = fields.Text(string="Note") + notee = fields.Text(string="Note SJ", help="Catatan untuk kirim barang") + note_info = fields.Text(string="Note", help="Catatan untuk pengiriman") state_approve_md = fields.Selection([ ('waiting', 'Waiting For Approve by MD'), ('pending', 'Pending (perlu koordinasi dengan MD)'), @@ -253,7 +253,7 @@ class StockPicking(models.Model): def _check_date_doc_kirim_modification(self): for record in self: - if record.last_update_date_doc_kirim: + if record.last_update_date_doc_kirim and not self.env.context.get('from_button_approve'): kirim_date = fields.Datetime.from_string(record.last_update_date_doc_kirim) now = fields.Datetime.now() @@ -275,7 +275,7 @@ class StockPicking(models.Model): if invoice and not self.env.context.get('active_model') == 'stock.picking': rec._check_date_doc_kirim_modification() - if rec.date_doc_kirim != invoice.invoice_date: + if rec.date_doc_kirim != invoice.invoice_date and not self.env.context.get('from_button_approve'): get_approval_invoice_date = self.env['approval.invoice.date'].search([('picking_id', '=', rec.id),('state', '=', 'draft')], limit=1) if get_approval_invoice_date and get_approval_invoice_date.state == 'draft': -- cgit v1.2.3 From add5cafc05aec0036fa1382c90dbf3abc8e1ecf5 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 24 Apr 2025 13:52:08 +0700 Subject: add validation barcode product --- indoteknik_custom/models/stock_picking.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index f812df86..a8a4a4e6 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1826,9 +1826,21 @@ class BarcodeProduct(models.Model): product_id = fields.Many2one('product.product', string='Product', required=True) barcode = fields.Char(string='Barcode') + def check_duplicate_barcode(self): + barcode_product = self.env['product.product'].search([('barcode', '=', self.barcode)]) + + if barcode_product: + raise UserError('Barcode sudah digunakan {}'.format(barcode_product.display_name)) + + barcode_box = self.env['product.product'].search([('barcode_box', '=', self.barcode)]) + + if barcode_box: + raise UserError('Barcode box sudah digunakan {}'.format(barcode_box.display_name)) + @api.constrains('barcode') def send_barcode_to_product(self): for record in self: + record.check_duplicate_barcode() if record.barcode and not record.product_id.barcode: record.product_id.barcode = record.barcode else: -- cgit v1.2.3 From 21653f522154475d9029c1e2b395960b58ecf47a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 24 Apr 2025 13:56:11 +0700 Subject: push --- 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 a8a4a4e6..8f8ab54d 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -141,7 +141,7 @@ class StockPicking(models.Model): ('cancel', 'Cancelled'), ], string='Status Reserve', tracking=True, copy=False, help="The current state of the stock picking.") notee = fields.Text(string="Note SJ", help="Catatan untuk kirim barang") - note_info = fields.Text(string="Note", help="Catatan untuk pengiriman") + note_info = fields.Text(string="Note Logistix (Text)", help="Catatan untuk pengiriman") state_approve_md = fields.Selection([ ('waiting', 'Waiting For Approve by MD'), ('pending', 'Pending (perlu koordinasi dengan MD)'), -- cgit v1.2.3 From 2db8d058d5b7c291669240df90afc0312d509939 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 24 Apr 2025 14:29:33 +0700 Subject: fix bug --- indoteknik_custom/models/barcoding_product.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/barcoding_product.py b/indoteknik_custom/models/barcoding_product.py index e28473ff..204c6128 100644 --- a/indoteknik_custom/models/barcoding_product.py +++ b/indoteknik_custom/models/barcoding_product.py @@ -17,16 +17,16 @@ class BarcodingProduct(models.Model): qty_pcs_box = fields.Char(string="Quantity Pcs Box") def check_duplicate_barcode(self): - barcode_product = self.env['product.product'].search([('barcode', '=', self.barcode)]) + if self.type in ['barcoding_box', 'barcoding']: + barcode_product = self.env['product.product'].search([('barcode', '=', self.barcode)]) - if barcode_product: - raise UserError('Barcode sudah digunakan {}'.format(barcode_product.display_name)) - - barcode_box = self.env['product.product'].search([('barcode_box', '=', self.barcode)]) - - if barcode_box: - raise UserError('Barcode box sudah digunakan {}'.format(barcode_box.display_name)) + if barcode_product: + raise UserError('Barcode sudah digunakan {}'.format(barcode_product.display_name)) + + barcode_box = self.env['product.product'].search([('barcode_box', '=', self.barcode)]) + if barcode_box: + raise UserError('Barcode box sudah digunakan {}'.format(barcode_box.display_name)) @api.constrains('barcode') def _send_barcode_to_product(self): -- cgit v1.2.3