summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIndoteknik . <it@fixcomart.co.id>2025-05-19 11:08:11 +0700
committerIndoteknik . <it@fixcomart.co.id>2025-05-19 11:08:11 +0700
commit60f1f3b3dbe988d8c0fda706fd25d3abe892238a (patch)
tree6137f2e40fe26ca7027ab5a95af5ad3bfaa3c5c2
parent5ef4a7e21e3dc3fc3ddebf002586c9e39c42a64b (diff)
(andri) penyesuaian selected shipping ketika estimate shipping
-rwxr-xr-xindoteknik_custom/models/sale_order.py193
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