summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindoteknik_custom/models/sale_order.py90
-rw-r--r--indoteknik_custom/views/res_partner.xml4
2 files changed, 53 insertions, 41 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 4ee82100..f09869da 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -258,7 +258,6 @@ class SaleOrder(models.Model):
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 [
@@ -271,29 +270,25 @@ class SaleOrder(models.Model):
self.carrier_id = False
self.delivery_amt = 0
- biteship_courier_codes = self._get_biteship_courier_codes()
-
- # Cari carrier yang namanya mengandung kode Biteship
+ # Dapatkan semua ID carrier untuk Biteship
biteship_carrier_ids = []
- for code in biteship_courier_codes:
- carriers = self.env['delivery.carrier'].search([
- ('name', 'ilike', code)
- ])
- if carriers:
- biteship_carrier_ids.extend(carriers.ids)
- # Hapus duplikat
- biteship_carrier_ids = list(set(biteship_carrier_ids))
+ # Gunakan SQL langsung untuk menghindari masalah ORM
+ self.env.cr.execute("""
+ SELECT delivery_carrier_id
+ FROM rajaongkir_kurir
+ WHERE name IN %s
+ """, (tuple(self._get_biteship_courier_codes()),))
- if self.select_shipping_option == 'custom':
- # Tampilkan carrier yang bukan dari Biteship
- domain = [('id', 'not in', biteship_carrier_ids)] if biteship_carrier_ids else []
- return {'domain': {'carrier_id': domain}}
+ # Ambil ID numerik hasil query
+ biteship_carrier_ids = [row[0] for row in self.env.cr.fetchall() if row[0]]
- elif self.select_shipping_option == 'biteship':
- # Tampilkan hanya carrier dari Biteship
+ if self.select_shipping_option == 'biteship':
domain = [('id', 'in', biteship_carrier_ids)] if biteship_carrier_ids else []
- return {'domain': {'carrier_id': domain}}
+ else: # 'custom'
+ domain = [('id', 'not in', biteship_carrier_ids)] if biteship_carrier_ids else []
+
+ return {'domain': {'carrier_id': domain}}
@api.constrains('fee_third_party', 'delivery_amt', 'biaya_lain_lain')
def _check_total_margin_excl_third_party(self):
@@ -490,6 +485,7 @@ class SaleOrder(models.Model):
return total_weight
def action_estimate_shipping_biteship(self):
+
total_weight = self._validate_for_shipping_estimate()
# Konversi berat ke gram untuk Biteship
@@ -509,6 +505,10 @@ class SaleOrder(models.Model):
"length": 10
}]
+ # Coba dapatkan data koordinat dari alamat pengiriman
+ shipping_address = self.real_shipping_id
+ _logger.info(f"Shipping Address: {shipping_address}")
+
# Data asal (tetap gudang Bandengan)
origin_data = {
"origin_latitude": -6.3031123,
@@ -519,37 +519,41 @@ class SaleOrder(models.Model):
destination_data = {}
use_coordinate = False
- shipping_address = self.real_shipping_id
-
# 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:
+ if hasattr(shipping_address, 'latitude') and hasattr(shipping_address, 'longtitude'):
+ if shipping_address.latitude and shipping_address.longtitude:
try:
+ # Validasi format koordinat
lat = float(shipping_address.latitude)
- lng = float(shipping_address.longitude)
+ lng = float(shipping_address.longtitude)
destination_data = {
"destination_latitude": lat,
"destination_longitude": lng
}
use_coordinate = True
+ _logger.info(f"Using coordinates: lat={lat}, lng={lng}")
except (ValueError, TypeError):
+ _logger.warning(f"Invalid coordinates, falling back to postal code")
use_coordinate = False
- # Jika koordinat tidak tersedia, gunakan kode pos
+ # Jika koordinat tidak tersedia atau tidak valid, gunakan kode pos
if not use_coordinate:
if shipping_address.zip:
- origin_data = {"origin_postal_code": 14440}
+ origin_data = {"origin_postal_code": 14440} # Reset origin untuk mode kode pos
destination_data = {
"destination_postal_code": shipping_address.zip
}
+ _logger.info(f"Using postal code: {shipping_address.zip}")
else:
raise UserError("Tidak dapat mengestimasikan ongkir: Kode pos tujuan tidak tersedia.")
- # Filter kurir berdasarkan shipping method jika dipilih
- couriers = self.carrier_id.name.lower() if self.carrier_id else ','.join(self._get_biteship_courier_codes())
+ # Siapkan daftar kurir
+ couriers = ','.join(self._get_biteship_courier_codes())
- # Panggil API Biteship
+ # Panggil API Biteship dengan format yang benar
api_mode = "koordinat" if use_coordinate else "kode_pos"
+ _logger.info(f"Calling Biteship API with mode: {api_mode}")
+
result = self._call_biteship_api(origin_data, destination_data, items, couriers)
if not result:
@@ -562,14 +566,19 @@ 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
@@ -577,12 +586,13 @@ 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"
+ etd = "1-3 days" # Default fallback
# Buat shipping option
try:
@@ -595,18 +605,19 @@ 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}.")
+ raise UserError(f"Tidak ada layanan pengiriman ditemukan untuk kode pos {destination_data}. Mohon periksa kembali kode pos atau gunakan metode pengiriman lain.")
# Set opsi pertama sebagai default
self.shipping_option_id = shipping_options[0].id
self.delivery_amt = shipping_options[0].price
- # Tampilkan lokasi pengiriman dengan format yang lebih baik
+ # Format pesan untuk log yang lebih informatif
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')})"
@@ -620,17 +631,14 @@ class SaleOrder(models.Model):
for opt in shipping_options
])
- # 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
+ # Log hasil estimasi dengan format yang lebih baik
self.message_post(
- body=f"<b>Estimasi Ongkir Biteship ({origin_info} → {destination_info}):</b><br/>{shipping_method_info}<br/>{option_list}",
+ body=f"<b>Estimasi Ongkir Biteship ({origin_info} → {destination_info}):</b><br/>{option_list}",
message_type="comment"
)
# Simpan informasi untuk note ekspedisi
+ selected_option = shipping_options[0] # Opsi pertama dipilih sebagai default
self.note_ekspedisi = f"Pengiriman: {selected_option.name} - Rp {selected_option.price:,.0f} ({selected_option.etd}) [via {api_mode}]"
return {
@@ -1435,7 +1443,7 @@ class SaleOrder(models.Model):
raise UserError("This order not yet approved by customer procurement or director")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
- raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
if not order.commitment_date and order.create_date > datetime(2024, 9, 12):
raise UserError("Expected Delivery Date kosong, wajib diisi")
@@ -1462,7 +1470,7 @@ class SaleOrder(models.Model):
if (partner.customer_type == 'pkp' or order.customer_type == 'pkp') and order.sppkp != partner.sppkp:
raise UserError("SPPKP berbeda pada Master Data Customer")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
- raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
if not order.user_id.active:
raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact")
@@ -1673,7 +1681,7 @@ class SaleOrder(models.Model):
raise UserError("This order not yet approved by customer procurement or director")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
- raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
if not order.commitment_date and order.create_date > datetime(2024, 9, 12):
raise UserError("Expected Delivery Date kosong, wajib diisi")
diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml
index cb9fa3ac..9fb6530c 100644
--- a/indoteknik_custom/views/res_partner.xml
+++ b/indoteknik_custom/views/res_partner.xml
@@ -65,6 +65,10 @@
<group name="purchase" position="inside">
<field name="leadtime"/>
</group>
+ <field name="vat" position="before">
+ <field name="latitude"/>
+ <field name="longtitude"/>
+ </field>
<field name="vat" position="after">
<field name="email_finance" widget="email"/>
<field name="email_sales" widget="email"/>