From d6f3060b46582ddd78f596ce3527871cae1b2b46 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Tue, 3 Jun 2025 14:08:30 +0700 Subject: (andri) ganti referensi dari no SO ke no BU OUT --- indoteknik_custom/models/stock_picking.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index a2935a07..39872ecb 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -568,13 +568,13 @@ class StockPicking(models.Model): _logger.info(f"Items data standard: {items_data_standard}") _logger.info(f"Items data instant: {items_data_instant}") - # Bangun payload dasar + payload = { "origin_coordinate": { "latitude": -6.3031123, "longitude": 106.7794934999 }, - "reference_id": self.sale_id.name, + "reference_id": self.name, # PERUBAHAN: Gunakan nomor BU/OUT "shipper_contact_name": self.carrier_id.pic_name or '', "shipper_contact_phone": self.carrier_id.pic_phone or '', "shipper_organization": self.carrier_id.name, @@ -587,6 +587,7 @@ class StockPicking(models.Model): "destination_address": self.real_shipping_id.street, "destination_postal_code": self.real_shipping_id.zip, "origin_note": "BELAKANG INDOMARET", + "destination_note": f"SO: {self.sale_id.name}", # PERUBAHAN: Tambahkan SO ke note "courier_type": self.sale_id.delivery_service_type or "reg", "courier_company": self.carrier_id.name.lower(), "delivery_type": "now", @@ -640,7 +641,9 @@ class StockPicking(models.Model): body=f"Biteship berhasil dilakukan.
" f"Kurir: {self.carrier_id.name}
" f"Tracking ID: {self.biteship_tracking_id or '-'}
" - f"Resi: {waybill_id or '-'}", + f"Resi: {waybill_id or '-'}
" + f"Reference: {self.name}
" + f"SO: {self.sale_id.name}", message_type="comment" ) -- cgit v1.2.3 From b519e0fdac46a64ffef87d27ba824038147d831b Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Tue, 3 Jun 2025 15:36:08 +0700 Subject: (andri) memastikan order sesuai dengan informasi barang yang ingin dikirim --- indoteknik_custom/models/stock_picking.py | 98 ++++++++++++------------------- 1 file changed, 39 insertions(+), 59 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 39872ecb..cdff6e32 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -526,7 +526,6 @@ class StockPicking(models.Model): if self.biteship_tracking_id: raise UserError(f"Order ini sudah dikirim ke Biteship. Dengan Tracking Id: {self.biteship_tracking_id}") - # Fungsi bantu: menentukan apakah kurir perlu koordinat def is_courier_need_coordinates(service_code): return service_code in [ "instant", "same_day", "instant_car", @@ -534,47 +533,42 @@ class StockPicking(models.Model): "cdd_bak", "cdd_box", "engkel_box", "engkel_bak" ] - # Ambil order line - products = self.env['sale.order.line'].search([('order_id', '=', self.sale_id.id)]) - - # Bangun data items untuk standard - def build_items_data(lines): - return [{ - "name": line.product_id.name, - "description": line.name, - "value": line.price_unit, - "quantity": line.product_uom_qty, - "weight": line.weight*1000 - } for line in lines] - - items_data_standard = build_items_data(products) + # ✅ Ambil item dari move_line_ids_with_package (qty_done > 0) + items = [] + for ml in self.move_line_ids_without_package: + if ml.qty_done <= 0: + continue - # Bangun data items untuk pengiriman instant - items_data_instant = [] - for move_line in self.move_line_ids_without_package: - order_line = self.env['sale.order.line'].search([ + product = ml.product_id + weight = product.weight or 0.1 # default minimal + line = ml.sale_line_id or self.env['sale.order.line'].search([ ('order_id', '=', self.sale_id.id), - ('product_id', '=', move_line.product_id.id) + ('product_id', '=', product.id) ], limit=1) - if order_line: - items_data_instant.append({ - "name": order_line.product_id.name, - "description": order_line.name, - "value": order_line.price_unit, - "quantity": move_line.qty_done, - "weight": order_line.weight*1000 - }) + value = line.price_unit if line else 0 + description = line.name if line else product.name + + items.append({ + "name": product.name, + "description": description, + "value": value, + "quantity": ml.qty_done, + "weight": int(weight * 1000), + }) - _logger.info(f"Items data standard: {items_data_standard}") - _logger.info(f"Items data instant: {items_data_instant}") + if not items: + raise UserError("Pengiriman tidak dapat dilakukan karena tidak ada barang yang divalidasi (qty_done = 0).") + + shipping_partner = self.real_shipping_id + courier_service_code = self.sale_id.delivery_service_type or "reg" payload = { "origin_coordinate": { "latitude": -6.3031123, "longitude": 106.7794934999 }, - "reference_id": self.name, # PERUBAHAN: Gunakan nomor BU/OUT + "reference_id": self.name, "shipper_contact_name": self.carrier_id.pic_name or '', "shipper_contact_phone": self.carrier_id.pic_phone or '', "shipper_organization": self.carrier_id.name, @@ -582,38 +576,26 @@ class StockPicking(models.Model): "origin_contact_phone": "081717181922", "origin_address": "Jl. Bandengan Utara Komp A & BRT. Penjaringan, Kec. Penjaringan, Jakarta (BELAKANG INDOMARET) KOTA JAKARTA UTARA PENJARINGAN", "origin_postal_code": 14440, - "destination_contact_name": self.real_shipping_id.name, - "destination_contact_phone": self.real_shipping_id.phone or self.real_shipping_id.mobile, - "destination_address": self.real_shipping_id.street, - "destination_postal_code": self.real_shipping_id.zip, + "destination_contact_name": shipping_partner.name, + "destination_contact_phone": shipping_partner.phone or shipping_partner.mobile, + "destination_address": shipping_partner.street, + "destination_postal_code": shipping_partner.zip, "origin_note": "BELAKANG INDOMARET", - "destination_note": f"SO: {self.sale_id.name}", # PERUBAHAN: Tambahkan SO ke note - "courier_type": self.sale_id.delivery_service_type or "reg", + "destination_note": f"SO: {self.sale_id.name}", + "courier_type": courier_service_code, "courier_company": self.carrier_id.name.lower(), "delivery_type": "now", - "items": items_data_standard + "items": items } - _logger.info(f"Delivery service type: {self.sale_id.delivery_service_type}") - _logger.info(f"Carrier: {self.carrier_id.name}") - _logger.info(f"Payload awal: {payload}") - - # Tambahkan destination_coordinate jika diperlukan - if is_courier_need_coordinates(self.sale_id.delivery_service_type): - if not self.real_shipping_id.latitude or not self.real_shipping_id.longtitude: + if is_courier_need_coordinates(courier_service_code): + if not shipping_partner.latitude or not shipping_partner.longtitude: raise UserError("Alamat tujuan tidak memiliki koordinat (latitude/longitude).") - # items_to_use = items_data_instant if items_data_instant else items_data_standard - if not items_data_instant: - raise UserError("Pengiriman instant membutuhkan produk yang sudah diproses (qty_done > 0). Harap lakukan validasi picking terlebih dahulu.") - - payload.update({ - "destination_coordinate": { - "latitude": self.real_shipping_id.latitude, - "longitude": self.real_shipping_id.longtitude, - }, - "items": items_data_instant - }) + payload["destination_coordinate"] = { + "latitude": shipping_partner.latitude, + "longitude": shipping_partner.longtitude, + } _logger.info(f"Payload untuk Biteship: {payload}") @@ -633,7 +615,7 @@ class StockPicking(models.Model): self.biteship_id = data.get("id", "") self.biteship_tracking_id = data.get("courier", {}).get("tracking_id", "") self.biteship_waybill_id = data.get("courier", {}).get("waybill_id", "") - self.delivery_tracking_no = data.get("courier", {}).get("waybill_id", "") + self.delivery_tracking_no = self.biteship_waybill_id waybill_id = self.biteship_waybill_id @@ -656,13 +638,11 @@ class StockPicking(models.Model): 'type': 'rainbow_man', } } - else: error_data = response.json() error_message = error_data.get("error", "Unknown error") error_code = error_data.get("code", "No code provided") raise UserError(f"Error saat mengirim ke Biteship: {error_message} (Code: {error_code})") - @api.constrains('driver_departure_date') def constrains_driver_departure_date(self): -- cgit v1.2.3 From 8a9c08a21fd7d2ac63ef849d9417b11563092f0d Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Tue, 3 Jun 2025 21:10:12 +0700 Subject: (andri) perbaikan biteship pada stock picking --- indoteknik_custom/models/stock_picking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index cdff6e32..7e001299 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -541,9 +541,9 @@ class StockPicking(models.Model): product = ml.product_id weight = product.weight or 0.1 # default minimal - line = ml.sale_line_id or self.env['sale.order.line'].search([ + line = ml.move_id.sale_line_id or self.env['sale.order.line'].search([ ('order_id', '=', self.sale_id.id), - ('product_id', '=', product.id) + ('product_id', '=', ml.product_id.id) ], limit=1) value = line.price_unit if line else 0 -- cgit v1.2.3 From b892a11ae2e28d1ad2d42c1fba0fec875fdbf163 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 7 Jun 2025 08:34:54 +0700 Subject: (andri) fix bug shipping method --- indoteknik_custom/models/sale_order.py | 53 ++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index a86d43cb..9faafb11 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -256,6 +256,20 @@ class SaleOrder(models.Model): ('custom', 'Custom'), ], string='Shipping Option', help="Select shipping option for delivery", tracking=True) + @api.onchange('shipping_cost_covered') + def _onchange_shipping_cost_covered(self): + if self.shipping_cost_covered == 'indoteknik' and self.select_shipping_option == 'biteship': + self.shipping_cost_covered = 'customer' + return { + 'warning': { + 'title': "Biteship Tidak Diizinkan", + 'message': ( + "Biaya pengiriman ditanggung Indoteknik, sehingga tidak diizinkan menggunakan metode Biteship. " + "Pilihan penanggung biaya akan dikembalikan sebelumnya" + ) + } + } + def get_biteship_carrier_ids(self): courier_codes = tuple(self._get_biteship_courier_codes() or []) if not courier_codes: @@ -277,20 +291,29 @@ class SaleOrder(models.Model): if view_type == 'form': doc = etree.XML(res['arch']) - carrier_ids = self.get_biteship_carrier_ids() - if carrier_ids: - carrier_ids_str = '(' + ','.join(str(x) for x in carrier_ids) + ')' - else: - carrier_ids_str = '(-1,)' # aman kalau kosong + # Ambil semua delivery_carrier_id dari mapping rajaongkir_kurir + biteship_ids = self.env['rajaongkir.kurir'].search([]).mapped('delivery_carrier_id.id') + biteship_ids = list(set(filter(None, biteship_ids))) # pastikan unik dan bukan None + + all_ids = self.env['delivery.carrier'].search([]).ids + custom_ids = list(set(all_ids) - set(biteship_ids)) - # ✅ Tambahkan log di sini - _logger.info("🛰️ Biteship Carrier IDs: %s", carrier_ids) - _logger.info("📦 Domain string to apply: [('id', 'in', %s)]", carrier_ids_str) + # Format sebagai string Python list + biteship_ids_str = ','.join(str(i) for i in biteship_ids) or '-1' + custom_ids_str = ','.join(str(i) for i in custom_ids) or '-1' + # Terapkan domain ke field carrier_id for node in doc.xpath("//field[@name='carrier_id']"): - node.set('domain', "[('id', 'in', %s)]" % carrier_ids_str) + # Domain tergantung select_shipping_option + node.set( + 'domain', + "[('id', 'in', [%s]) if select_shipping_option == 'biteship' else ('id', 'in', [%s])]" % + (biteship_ids_str, custom_ids_str) + ) + # Simpan kembali hasil XML ke arsitektur form res['arch'] = etree.tostring(doc, encoding='unicode') + return res # @api.onchange('shipping_option_id') @@ -477,6 +500,18 @@ class SaleOrder(models.Model): @api.onchange('select_shipping_option') def _onchange_select_shipping_option(self): + if self.select_shipping_option == 'biteship' and self.shipping_cost_covered == 'indoteknik': + self.select_shipping_option = self._origin.select_shipping_option if self._origin else 'custom' + return { + 'warning': { + 'title': "Biteship Tidak Diizinkan", + 'message': ( + "Biaya pengiriman ditanggung Indoteknik. Tidak diizinkan memilih metode Biteship. " + "Opsi pengiriman dikembalikan ke sebelumnya." + ) + } + } + self.shipping_option_id = False self.carrier_id = False self.delivery_amt = 0 -- cgit v1.2.3 From 288a7f333c1d37574dba76f3fb3f7216da259cae Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 7 Jun 2025 09:41:27 +0700 Subject: (andri) add field shipping option pada stock picking sebagai tambahan info --- indoteknik_custom/models/stock_picking.py | 5 +++++ indoteknik_custom/views/stock_picking.xml | 2 ++ 2 files changed, 7 insertions(+) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 7e001299..d6413b87 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -244,6 +244,11 @@ class StockPicking(models.Model): biteship_waybill_id = fields.Char(string="Biteship Waybill ID") final_seq = fields.Float(string='Remaining Time') shipping_method_so_id = fields.Many2one('delivery.carrier', string='Shipping Method SO', related='sale_id.carrier_id') + shipping_option_so_id = fields.Many2one('shipping.option', string='Shipping Option SO', related='sale_id.shipping_option_id') + select_shipping_option_so = fields.Selection([ + ('biteship', 'Biteship'), + ('custom', 'Custom'), + ], string='Shipping Type SO', related='sale_id.select_shipping_option') 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') diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 9b16639c..b0d55104 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -91,7 +91,9 @@ /> + + -- cgit v1.2.3 From de747091235c844d33bcf62b4d98af0d03251826 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Mon, 9 Jun 2025 11:37:19 +0700 Subject: (andri) fix note order biteship --- indoteknik_custom/models/stock_picking.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index d6413b87..d04b3d27 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -587,6 +587,7 @@ class StockPicking(models.Model): "destination_postal_code": shipping_partner.zip, "origin_note": "BELAKANG INDOMARET", "destination_note": f"SO: {self.sale_id.name}", + "order_note": f"SO: {self.sale_id.name}", "courier_type": courier_service_code, "courier_company": self.carrier_id.name.lower(), "delivery_type": "now", -- cgit v1.2.3