summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrisusilo48 <tri.susilo@altama.co.id>2025-02-21 11:29:14 +0700
committertrisusilo48 <tri.susilo@altama.co.id>2025-02-21 11:29:14 +0700
commit92222d326692652b2c4146e0e6040c74f75d4abc (patch)
tree5f9ad35cecad3659c06f824faeb868e688b7f3e0
parent6a1b03cbd12931784aee8226ed5f163dcae42081 (diff)
tracking
-rw-r--r--indoteknik_api/controllers/api_v1/stock_picking.py2
-rw-r--r--indoteknik_custom/models/stock_picking.py93
2 files changed, 89 insertions, 6 deletions
diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py
index 110cde8a..2fc4d8a5 100644
--- a/indoteknik_api/controllers/api_v1/stock_picking.py
+++ b/indoteknik_api/controllers/api_v1/stock_picking.py
@@ -101,7 +101,7 @@ class StockPicking(controller.Controller):
picking = picking_model.browse(id)
if not picking:
return self.response(None)
-
+ hostori = picking.get_tracking_detail()
return self.response(picking.get_tracking_detail())
@http.route(prefix + 'stock-picking/<id>/tracking', auth='public', method=['GET', 'OPTIONS'])
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index e7d9dbd5..49c17788 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -12,8 +12,15 @@ import base64
import requests
import time
import logging
+import re
+from deep_translator import GoogleTranslator
_logger = logging.getLogger(__name__)
+_biteship_url = "https://api.biteship.com/v1"
+_biteship_api_key = "biteship_test.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSW5kb3Rla25payIsInVzZXJJZCI6IjY3MTViYTJkYzVkMjdkMDAxMjRjODk2MiIsImlhdCI6MTcyOTQ5ODAwMX0.L6C73couP4-cgVEfhKI2g7eMCMo3YOFSRZhS-KSuHNA"
+
+
+
class StockPicking(models.Model):
_inherit = 'stock.picking'
# check_product_lines = fields.One2many('check.product', 'picking_id', string='Check Product', auto_join=True)
@@ -363,9 +370,10 @@ class StockPicking(models.Model):
raise UserError(f"Kesalahan tidak terduga: {str(e)}")
def action_send_to_biteship(self):
- url = "https://api.biteship.com/v1/orders"
- api_key = "biteship_test.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSW5kb3Rla25payIsInVzZXJJZCI6IjY3MTViYTJkYzVkMjdkMDAxMjRjODk2MiIsImlhdCI6MTcyOTQ5ODAwMX0.L6C73couP4-cgVEfhKI2g7eMCMo3YOFSRZhS-KSuHNA"
-
+
+ if self.biteship_tracking_id:
+ raise UserError(f"Order ini sudah dikirim ke Biteship. Dengan Tracking Id: {self.biteship_tracking_id}")
+
# Mencari data sale.order.line berdasarkan sale_id
products = self.env['sale.order.line'].search([('order_id', '=', self.sale_id.id)])
@@ -401,6 +409,7 @@ class StockPicking(models.Model):
})
payload = {
+ "reference_id " : self.sale_id.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,
@@ -433,14 +442,15 @@ class StockPicking(models.Model):
},
"items": items_data_instant
})
-
+
+ api_key = _biteship_api_key
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
# Kirim request ke Biteship
- response = requests.post(url, headers=headers, json=payload)
+ response = requests.post(_biteship_url+'/orders', headers=headers, json=payload)
if response.status_code == 200:
data = response.json()
@@ -448,6 +458,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", "")
return data
else:
@@ -1016,8 +1027,19 @@ class StockPicking(models.Model):
'waybill_number': self.delivery_tracking_no or '',
'delivery_status': None,
'eta': self.generate_eta_delivery(),
+ 'is_biteship': True if self.biteship_id else False,
'manifests': self.get_manifests()
}
+
+ if self.biteship_id :
+ histori = self.get_manifest_biteship()
+ response['manifests'] = histori.get("manifests", [])
+ response['delivered'] = histori.get("delivered", False) or self.sj_return_date != False or self.driver_arrival_date != False
+ response['status'] = self._map_status_biteship(histori.get("delivered"))
+
+ response
+
+ return response
if not self.waybill_id or len(self.waybill_id.manifest_ids) == 0:
response['delivered'] = self.sj_return_date != False or self.driver_arrival_date != False
@@ -1030,6 +1052,67 @@ class StockPicking(models.Model):
return response
+ def get_manifest_biteship(self):
+ api_key = _biteship_api_key
+ headers = {
+ "Authorization": f"Bearer {api_key}",
+ "Content-Type": "application/json"
+ }
+
+
+ manifests = []
+
+ try:
+ # Kirim request ke Biteship
+ response = requests.get(_biteship_url+'/trackings/'+self.biteship_tracking_id, headers=headers, json=manifests)
+ result = response.json()
+ if(result.get('success') == True):
+ history = result.get("history", [])
+ status = result.get("status", "")
+
+ for entry in reversed(history):
+ manifests.append({
+ "status": re.sub(r'[^a-zA-Z0-9\s]', ' ', entry["status"]).lower().capitalize(),
+ "datetime": self._convert_to_local_time(entry["updated_at"]),
+ "description": GoogleTranslator(source='auto', target='id').translate(entry["note"]),
+ })
+
+ return {
+ "manifests": manifests,
+ "delivered": status
+ }
+
+ return manifests
+ except Exception as e :
+ _logger.error(f"Error fetching Biteship order for picking {self.id}: {str(e)}")
+ return { 'error': str(e) }
+
+ def _convert_to_local_time(self, iso_date):
+ try:
+ dt_with_tz = waktu.fromisoformat(iso_date)
+ utc_dt = dt_with_tz.astimezone(pytz.utc)
+
+ local_tz = pytz.timezone("Asia/Jakarta")
+ local_dt = utc_dt.astimezone(local_tz)
+
+ return local_dt.strftime("%Y-%m-%d %H:%M:%S")
+ except Exception as e:
+ return str(e)
+
+ def _map_status_biteship(self, status):
+ status_mapping = {
+ "confirmed": "pending",
+ "scheduled": "pending",
+ "allocated": "pending",
+ "picking_up": "pending",
+ "picked": "shipment",
+ "cancelled": "cancelled",
+ "on_hold": "on_hold",
+ "dropping_off": "shipment",
+ "delivered": "completed"
+ }
+ return status_mapping.get(status, "Hubungi Admin")
+
def generate_eta_delivery(self):
current_date = datetime.datetime.now()
prepare_days = 3