diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-05 13:47:39 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-05 13:47:39 +0700 |
| commit | 82fbb8fa6c6ab05e85dd59316dc46231a00d1b5b (patch) | |
| tree | 9ea1d4a2af2edcf4f6bdf1eb495b3151592ad239 | |
| parent | 821f741178fa5aeba969eda95caf00275fb3c91e (diff) | |
push
| -rwxr-xr-x | fixco_custom/models/stock_picking.py | 261 |
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( |
