diff options
| author | Indoteknik . <it@fixcomart.co.id> | 2025-05-19 11:08:11 +0700 |
|---|---|---|
| committer | Indoteknik . <it@fixcomart.co.id> | 2025-05-19 11:08:11 +0700 |
| commit | 60f1f3b3dbe988d8c0fda706fd25d3abe892238a (patch) | |
| tree | 6137f2e40fe26ca7027ab5a95af5ad3bfaa3c5c2 | |
| parent | 5ef4a7e21e3dc3fc3ddebf002586c9e39c42a64b (diff) | |
(andri) penyesuaian selected shipping ketika estimate shipping
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 193 |
1 files changed, 68 insertions, 125 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 12c04f19..4ee82100 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -252,12 +252,13 @@ class SaleOrder(models.Model): select_shipping_option = fields.Selection([ ('biteship', 'Biteship'), ('custom', 'Custom'), - ], string='Select Shipping Option', help="Select shipping option for delivery") + ], string='Select Shipping Option', help="Select shipping option for delivery", Tracking=True) @api.onchange('shipping_option_id') def _onchange_shipping_option_id(self): if self.shipping_option_id: self.delivery_amt = self.shipping_option_id.price + self.note_ekspedisi = f"Pengiriman: {self.shipping_option_id.name} - Rp {self.shipping_option_id.price:,.0f} ({self.shipping_option_id.etd})" def _get_biteship_courier_codes(self): return [ @@ -267,6 +268,7 @@ class SaleOrder(models.Model): @api.onchange('select_shipping_option') def _onchange_select_shipping_option(self): self.shipping_option_id = False + self.carrier_id = False self.delivery_amt = 0 biteship_courier_codes = self._get_biteship_courier_codes() @@ -488,7 +490,6 @@ class SaleOrder(models.Model): return total_weight def action_estimate_shipping_biteship(self): - # Validasi data total_weight = self._validate_for_shipping_estimate() # Konversi berat ke gram untuk Biteship @@ -508,63 +509,47 @@ class SaleOrder(models.Model): "length": 10 }] - # Coba dapatkan data alamat tujuan - destination_data = {} - origin_data = {} - - # Persiapkan data alamat asal (Gudang) - # 1. Data tetap gudang Bandengan + # Data asal (tetap gudang Bandengan) origin_data = { - "origin_postal_code" : 14440, - # "origin_latitude": -6.1753924, - # "origin_longitude": 106.7794935, + "origin_latitude": -6.3031123, + "origin_longitude": 106.7794934, } - - # Coba dapatkan data alamat tujuan - if not self.real_shipping_id: - raise UserError("Alamat pengiriman (Real Delivery Address) harus diisi.") + + # Prioritaskan penggunaan koordinat jika tersedia + destination_data = {} + use_coordinate = False shipping_address = self.real_shipping_id - _logger.info(f"Shipping Address: {shipping_address}") - _logger.info(f"Shipping Address: {shipping_address.zip}") - # # Coba dapatkan koordinat dulu (jika tersedia) - # if hasattr(shipping_address, 'partner_latitude') and hasattr(shipping_address, 'partner_longitude'): - # if shipping_address.partner_latitude and shipping_address.partner_longitude: - # destination_data = { - # "destination_latitude": shipping_address.partner_latitude, - # "destination_longitude": shipping_address.partner_longitude - # } + # Cek apakah latitude dan longitude tersedia dan valid + if hasattr(shipping_address, 'latitude') and hasattr(shipping_address, 'longitude'): + if shipping_address.latitude and shipping_address.longitude: + try: + lat = float(shipping_address.latitude) + lng = float(shipping_address.longitude) + destination_data = { + "destination_latitude": lat, + "destination_longitude": lng + } + use_coordinate = True + except (ValueError, TypeError): + use_coordinate = False # Jika koordinat tidak tersedia, gunakan kode pos - if not destination_data and shipping_address.zip: - destination_data = { - "destination_postal_code": shipping_address.zip - } + if not use_coordinate: + if shipping_address.zip: + origin_data = {"origin_postal_code": 14440} + destination_data = { + "destination_postal_code": shipping_address.zip + } + else: + raise UserError("Tidak dapat mengestimasikan ongkir: Kode pos tujuan tidak tersedia.") - # Jika kode pos tidak tersedia, gunakan alamat lengkap - # if not destination_data: - # # Buat alamat lengkap - # full_address = f"{shipping_address.street or ''}" - # if shipping_address.street2: - # full_address += f", {shipping_address.street2}" - - # destination_data = { - # "address": full_address, - # "area": shipping_address.kota_id.name if shipping_address.kota_id else "", - # "suburb": shipping_address.kecamatan_id.name if shipping_address.kecamatan_id else "", - # "province": shipping_address.state_id.name if shipping_address.state_id else "", - # "postcode": shipping_address.zip or "" - # } - - # Siapkan daftar kurir yang valid untuk Biteship - couriers = ','.join(self._get_biteship_courier_codes()) - - # Jika tidak ada data tujuan yang valid - if not destination_data: - raise UserError("Tidak dapat mengestimasikan ongkir: Alamat pengiriman tidak lengkap.") - - # Panggil API Biteship dengan format yang benar + # Filter kurir berdasarkan shipping method jika dipilih + couriers = self.carrier_id.name.lower() if self.carrier_id else ','.join(self._get_biteship_courier_codes()) + + # Panggil API Biteship + api_mode = "koordinat" if use_coordinate else "kode_pos" result = self._call_biteship_api(origin_data, destination_data, items, couriers) if not result: @@ -577,19 +562,14 @@ class SaleOrder(models.Model): shipping_options = [] shipping_services = result.get('pricing', []) - _logger.info(f"Ditemukan {len(shipping_services)} layanan pengiriman") - for service in shipping_services: courier_code = service.get('courier_code', '').lower() courier_name = service.get('courier_name', '') service_name = service.get('courier_service_name', '') price = service.get('price', 0) - _logger.info(f"Layanan: {courier_name} - {service_name}, Harga: {price}") - # Lewati layanan dengan harga 0 if not price: - _logger.warning(f"Melewati layanan dengan harga 0: {courier_name} - {service_name}") continue # Format estimasi waktu @@ -597,13 +577,12 @@ class SaleOrder(models.Model): shipment_range = service.get('shipment_duration_range', '') shipment_unit = service.get('shipment_duration_unit', 'days') - # Gunakan duration jika tersedia, jika tidak, buat dari range if duration: etd = duration elif shipment_range: etd = f"{shipment_range} {shipment_unit}" else: - etd = "1-3 days" # Default fallback + etd = "1-3 days" # Buat shipping option try: @@ -616,36 +595,50 @@ class SaleOrder(models.Model): }) shipping_options.append(shipping_option) - _logger.info(f"Berhasil membuat opsi pengiriman: {courier_name} - {service_name}") except Exception as e: _logger.error(f"Gagal membuat opsi pengiriman: {str(e)}") # Jika tidak ada opsi pengiriman if not shipping_options: - raise UserError(f"Tidak ada layanan pengiriman ditemukan untuk kode pos {destination_data}. Mohon periksa kembali kode pos atau gunakan metode pengiriman lain.") + raise UserError(f"Tidak ada layanan pengiriman ditemukan untuk kode pos {destination_data}.") # Set opsi pertama sebagai default self.shipping_option_id = shipping_options[0].id self.delivery_amt = shipping_options[0].price - # Format pesan untuk log + # Tampilkan lokasi pengiriman dengan format yang lebih baik + if use_coordinate: + origin_info = f"Koordinat ({origin_data.get('origin_latitude')}, {origin_data.get('origin_longitude')})" + destination_info = f"Koordinat ({destination_data.get('destination_latitude')}, {destination_data.get('destination_longitude')})" + else: + origin_info = f"Kode Pos {origin_data.get('origin_postal_code')}" + destination_info = f"Kode Pos {destination_data.get('destination_postal_code')}" + + # Format daftar opsi pengiriman option_list = '<br/>'.join([ f"{opt.name}: Rp {opt.price:,.0f} ({opt.etd})" for opt in shipping_options ]) - # Log hasil estimasi + # Tampilkan informasi tentang kurir yang dipilih + selected_option = shipping_options[0] + shipping_method_info = f"<b>Metode Pengiriman:</b> {self.carrier_id.name}" if self.carrier_id else "" + + # Log hasil estimasi dengan format yang lebih baik dan informasi kurir self.message_post( - body=f"<b>Estimasi Ongkir Biteship (Kode Pos {origin_data} → {destination_data}):</b><br/>{option_list}", + body=f"<b>Estimasi Ongkir Biteship ({origin_info} → {destination_info}):</b><br/>{shipping_method_info}<br/>{option_list}", message_type="comment" ) + # Simpan informasi untuk note ekspedisi + self.note_ekspedisi = f"Pengiriman: {selected_option.name} - Rp {selected_option.price:,.0f} ({selected_option.etd}) [via {api_mode}]" + return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': 'Estimasi Ongkir Berhasil', - 'message': f'Mendapatkan {len(shipping_options)} opsi pengiriman', + 'message': f'Mendapatkan {len(shipping_options)} opsi pengiriman menggunakan {api_mode}', 'type': 'success', 'sticky': False, } @@ -663,59 +656,16 @@ class SaleOrder(models.Model): if not couriers: couriers = ','.join(self._get_biteship_courier_codes()) - - # # Cek apakah kita menggunakan koordinat (paling akurat) - # has_origin_coords = ('origin_latitude' in origin_data and 'origin_longitude' in origin_data) - # has_dest_coords = ('destination_latitude' in destination_data and 'destination_longitude' in destination_data) - - # Cek apakah kita menggunakan kode pos - has_origin_postal = ('origin_postal_code' in origin_data) - has_dest_postal = ('destination_postal_code' in destination_data) - _logger.info(f"Origin Data: {has_origin_postal}") - _logger.info(f"Destination Data: {has_dest_postal}") - # Tentukan payload berdasarkan data yang tersedia - # if has_origin_coords and has_dest_coords: - # # Mode koordinat - paling akurat - # payload = { - # "origin_latitude": origin_data.get('origin_latitude'), - # "origin_longitude": origin_data.get('origin_longitude'), - # "destination_latitude": destination_data.get('destination_latitude'), - # "destination_longitude": destination_data.get('destination_longitude'), - # "couriers": couriers, - # "items": items - # } - # api_mode = "koordinat" - # elif has_origin_postal and has_dest_postal: - if has_origin_postal and has_dest_postal: - # Mode kode pos - fallback 1 - payload = { - "origin_postal_code": origin_data.get('origin_postal_code'), - "destination_postal_code": destination_data.get('destination_postal_code'), - "couriers": couriers, - "items": items - } - api_mode = "kode_pos" - # else: - # # Mode alamat lengkap - fallback 2 - # payload = { - # "origin": { - # "address": origin_data.get('address', ''), - # "area": origin_data.get('area', ''), - # "suburb": origin_data.get('suburb', ''), - # "province": origin_data.get('province', ''), - # "postcode": origin_data.get('postcode', '') - # }, - # "destination": { - # "address": destination_data.get('address', ''), - # "area": destination_data.get('area', ''), - # "suburb": destination_data.get('suburb', ''), - # "province": destination_data.get('province', ''), - # "postcode": destination_data.get('postcode', '') - # }, - # "couriers": couriers, - # "items": items - # } - # api_mode = "alamat_lengkap" + + # Persiapkan payload dengan menggabungkan origin, destination, dan items + payload = { + **origin_data, + **destination_data, + "couriers": couriers, + "items": items + } + + api_mode = "koordinat" if "destination_latitude" in destination_data else "kode_pos" try: _logger.info(f"Calling Biteship API with mode: {api_mode}") @@ -723,25 +673,18 @@ class SaleOrder(models.Model): response = requests.post(url, headers=headers, json=payload, timeout=30) - # Log response untuk debugging _logger.info(f"Biteship API Status Code: {response.status_code}") if response.status_code != 200: _logger.error(f"Biteship API Error Response: {response.text}") if response.status_code == 200: result = response.json() - result['api_mode'] = api_mode # Tambahkan info mode API untuk referensi + result['api_mode'] = api_mode # Tambahkan info mode API return result else: error_msg = response.text _logger.error(f"Error calling Biteship API: {response.status_code} - {error_msg}") return False - except requests.exceptions.Timeout: - _logger.error("Timeout connecting to Biteship API") - return False - except requests.exceptions.ConnectionError: - _logger.error("Connection error to Biteship API") - return False except Exception as e: _logger.error(f"Exception calling Biteship API: {str(e)}") return False |
