summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2026-01-05 13:47:39 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2026-01-05 13:47:39 +0700
commit82fbb8fa6c6ab05e85dd59316dc46231a00d1b5b (patch)
tree9ea1d4a2af2edcf4f6bdf1eb495b3151592ad239
parent821f741178fa5aeba969eda95caf00275fb3c91e (diff)
push
-rwxr-xr-xfixco_custom/models/stock_picking.py261
1 files changed, 261 insertions, 0 deletions
diff --git a/fixco_custom/models/stock_picking.py b/fixco_custom/models/stock_picking.py
index e86f842..0a3ca39 100755
--- a/fixco_custom/models/stock_picking.py
+++ b/fixco_custom/models/stock_picking.py
@@ -385,6 +385,9 @@ class StockPicking(models.Model):
def get_shipping_parameter(self):
try:
+ if 'Blibli' in self.partner_id.name or 'BLIBLI' in self.partner_id.name:
+ self.get_shipping_parameter_blibli()
+
order_id = self.order_reference
authorization = self.sign_request(1)
@@ -456,9 +459,114 @@ class StockPicking(models.Model):
except Exception as e:
raise UserError(_("Error: %s") % str(e))
+ def get_shipping_parameter_blibli(self):
+ try:
+ if not self.order_reference:
+ return
+
+ # ==============================
+ # SPLIT ORDER REFERENCE
+ # ==============================
+ order_refs = [
+ ref.strip()
+ for ref in self.order_reference.split(",")
+ if ref.strip()
+ ]
+
+ # API ini WAJIB 1 order per call
+ authorization = self.sign_request(1)
+ headers = {
+ 'Content-Type': 'application/json',
+ 'X-Advai-Country': 'ID',
+ 'Authorization': authorization
+ }
+
+ url = "https://api.ginee.com/openapi/logistics/v1/get-shipping-parameter"
+
+ # ==============================
+ # LOOP PER ORDER ID
+ # ==============================
+ for order_id in order_refs:
+ payload = {
+ "orderId": order_id
+ }
+
+ response = requests.post(
+ url,
+ headers=headers,
+ data=json.dumps(payload)
+ )
+
+ try:
+ res = response.json()
+ except Exception:
+ raise UserError(
+ "Invalid JSON response from Ginee for order %s"
+ % order_id
+ )
+
+ if res.get("code") != "SUCCESS":
+ raise UserError(
+ "Ginee Error (%s): %s"
+ % (order_id, res.get("message"))
+ )
+
+ data = res.get("data", {})
+
+ # ==============================
+ # BASIC FIELDS
+ # ==============================
+ self.ginee_delivery_type = data.get("deliveryType")
+ self.ginee_tracking_no = data.get("logisticsTrackingNumber")
+ self.ginee_invoice_no = data.get("invoiceNumber")
+
+ # ==============================
+ # FIND PROVIDER
+ # ==============================
+ provider_id = None
+ provider_name = None
+ logistics_type = None
+
+ for lg in data.get("logistics", []) or []:
+ details = lg.get("logisticDetailList") or []
+ if details:
+ d = details[0]
+ provider_id = d.get("logisticsProviderId")
+ provider_name = d.get("logisticsProviderName")
+ logistics_type = lg.get("logisticsDeliveryType")
+ break
+
+ self.ginee_provider_id = provider_id
+ self.ginee_provider_name = provider_name
+ self.ginee_delivery_type = logistics_type or self.ginee_delivery_type
+
+ # ==============================
+ # PICKUP ADDRESS
+ # ==============================
+ addresses = data.get("addresses") or []
+ if addresses:
+ first = addresses[0]
+ self.ginee_address = first.get("address")
+ self.ginee_address_id = first.get("addressId")
+
+ times = first.get("pickupTimeList") or []
+ if times:
+ self.ginee_pickup_time_id = times[0].get("pickupTimeId")
+
+ # ==============================
+ # OPTIONAL: DELAY (ANTI RATE LIMIT)
+ # ==============================
+ time.sleep(0.2)
+
+ except Exception as e:
+ raise UserError(_("Error: %s") % str(e))
+
def ship_order(self):
try:
+
+ if 'Blibli' in self.partner_id.name or 'BLIBLI' in self.partner_id.name:
+ self.ship_order_blibli()
order_id = self.order_reference
authorization = self.sign_request(2) # index 2 -> ship-order
@@ -641,6 +749,159 @@ class StockPicking(models.Model):
except Exception as e:
raise UserError(_("Error: %s") % str(e))
+ def ship_order_blibli(self):
+ try:
+ if not self.order_reference:
+ return False
+
+ # ==============================
+ # SPLIT ORDER IDS
+ # ==============================
+ order_refs = [
+ ref.strip()
+ for ref in self.order_reference.split(",")
+ if ref.strip()
+ ]
+
+ if not order_refs:
+ return False
+
+ # ==============================
+ # AUTH & HEADER (ONCE)
+ # ==============================
+ authorization = self.sign_request(2)
+ headers = {
+ 'Content-Type': 'application/json',
+ 'X-Advai-Country': 'ID',
+ 'Authorization': authorization
+ }
+
+ platform = self._get_platform_from_channel() or ""
+
+ # ==============================
+ # COMMON SHIPPING DATA (SOURCE OF TRUTH)
+ # ==============================
+ base_shipping = {
+ "deliveryType": self.ginee_delivery_type,
+ "shippingProvider": self.ginee_provider_name,
+ "shippingProviderId": self.ginee_provider_id,
+ "trackingNo": self.ginee_tracking_no,
+ "invoiceNumber": self.ginee_invoice_no,
+ "addressId": self.ginee_address_id,
+ "address": self.ginee_address,
+ "pickupTimeId": self.ginee_pickup_time_id,
+ }
+
+ order_ships = []
+
+ # ==============================
+ # BUILD ORDER SHIPS
+ # ==============================
+ for order_id in order_refs:
+ order_data = {
+ "orderId": order_id,
+ "deliveryType": base_shipping["deliveryType"],
+ }
+
+ dt = base_shipping["deliveryType"]
+
+ # ==============================
+ # PLATFORM RULES
+ # ==============================
+ def add(*keys):
+ for k in keys:
+ if base_shipping.get(k):
+ order_data[k] = base_shipping[k]
+
+ if platform == "SHOPEE":
+ if dt == "PICK_UP":
+ add("shippingProvider", "pickupTimeId", "addressId", "address")
+ elif dt == "DROP_OFF":
+ add("shippingProvider")
+ elif dt == "MANUAL_SHIP":
+ add("shippingProvider", "trackingNo")
+
+ elif platform == "TOKOPEDIA":
+ if dt in ["PICK_UP", "MANUAL_SHIP"]:
+ add("shippingProvider", "trackingNo")
+ elif dt == "DROP_OFF":
+ add("shippingProvider")
+
+ elif platform == "LAZADA":
+ if dt == "PICK_UP":
+ add("shippingProvider", "address", "addressId", "pickupTimeId")
+ elif dt == "DROP_OFF":
+ add("shippingProvider", "invoiceNumber")
+
+ elif platform == "TIKTOK":
+ if dt == "PICK_UP":
+ order_data.update({
+ "shippingProvider": base_shipping["shippingProvider"],
+ "pickupStartTime": base_shipping["pickupTimeId"] or "",
+ "pickupEndTime": base_shipping["pickupTimeId"] or "",
+ })
+ elif dt == "DROP_OFF":
+ add("shippingProvider")
+
+ elif platform == "ZALORA":
+ if dt == "DROP_OFF":
+ add("trackingNo", "invoiceNumber")
+
+ elif platform == "AKULAKU":
+ if dt in ["PICK_UP", "DROP_OFF"]:
+ add("shippingProvider", "shippingProviderId", "addressId", "address")
+ elif dt == "MANUAL_SHIP":
+ add("shippingProvider", "shippingProviderId", "trackingNo")
+
+ elif platform == "BUKALAPAK":
+ if dt in ["PICK_UP", "DROP_OFF"]:
+ add("shippingProvider")
+ elif dt == "MANUAL_SHIP":
+ add("shippingProvider", "trackingNo")
+
+ elif platform == "BLIBLI":
+ if dt == "PICK_UP":
+ add("shippingProvider")
+ elif dt == "DROP_OFF":
+ add("shippingProvider", "trackingNo")
+
+ else:
+ if dt == "PICK_UP":
+ add("shippingProvider", "pickupTimeId", "addressId", "address")
+ elif dt == "DROP_OFF":
+ add("shippingProvider")
+ elif dt == "MANUAL_SHIP":
+ add("shippingProvider", "trackingNo")
+
+ order_ships.append(order_data)
+
+ # ==============================
+ # FINAL PAYLOAD (1 CALL ONLY)
+ # ==============================
+ payload = {
+ "orderShips": order_ships
+ }
+
+ url = "https://api.ginee.com/openapi/order/v3/batchShipping"
+
+ response = requests.post(
+ url,
+ headers=headers,
+ data=json.dumps(payload)
+ )
+
+ res = response.json()
+
+ if res.get("code") != "SUCCESS":
+ raise UserError("Ship Order Error: %s" % res.get("message"))
+
+ self.ginee_task_id = res.get("data") or False
+ return True
+
+ except Exception as e:
+ raise UserError(_("Error: %s") % str(e))
+
+
def sign_request(self, array_num):
signData = '$'.join(['POST', Request_URI[array_num]]) + '$'
authorization = ACCESS_KEY + ':' + base64.b64encode(