본문 바로가기

모각코/2023 동계

[2023 동계모각코] 5회차(23. 2. 1.) 결과

  • ERPNext 시스템 shipstation API 결합
def create_shipment(self, pickup_address, delivery_address, shipment_parcel, description_of_content,
		pickup_date, value_of_goods, service_info, pickup_contact=None, delivery_contact=None):
        # Create a transaction at ShipStation
        if not self.enabled or not self.api_id or not self.api_password:
            return []
      
        self.set_shipstation_specific_fields(pickup_contact, delivery_contact)
        pickup_address.address_title = self.trim_address(pickup_address)
        delivery_address.address_title = self.trim_address(delivery_address)
        parcel_list = self.get_parcel_list(json.loads(shipment_parcel), description_of_content)
        url = f'{BASE_URL}/shipments/createlabel'

        ship_from_info = self.get_pickup_delivery_info(pickup_address, pickup_contact)
        ship_to_info = self.get_pickup_delivery_info(delivery_address, delivery_contact)

        # Basic Authentication 헤더 생성
        auth_header = base64.b64encode(f"{self.api_id}:{self.api_password}".encode("utf-8")).decode("utf-8")
        headers = {
            "Authorization": f"Basic {auth_header}",
            "Content-Type": "application/json"
        }

        carrier_code = CARRIER_CODE
        service_code = service_info["service_code"]
        package_code = "package"
        confirmation = "delivery"
        ship_date = pickup_date
        weight = {
            "value": parcel_list[0]["weight"] * 1000,
            "units": "grams"
        }
        dimensions = {
            "units": "centimeters",
            "length": parcel_list[0]["length"],
            "width": parcel_list[0]["width"],
            "height": parcel_list[0]["height"]
        }

        ship_from = {
            "name": ship_from_info["person"]["firstname"] + " " + ship_from_info["person"]["lastname"],
            "company": ship_from_info["company"],
            "street1": ship_from_info["address"]["street"],
            "street2": ship_from_info["address"]["addressInfo1"],
            "street3": None,
            "city": ship_from_info["address"]["city"],
            "state": pickup_address["state"],
            "postalCode": ship_from_info["address"]["zip"],
            "country": ship_from_info["address"]["countryCode"],
            "phone": ship_from_info["phone"]["phoneNumberPrefix"] + " " + ship_from_info["phone"]["phoneNumber"],
            "residential": False
        }
        ship_to = {
            "name": ship_to_info["person"]["firstname"] + " " + ship_to_info["person"]["lastname"],
            "company": ship_to_info["company"],
            "street1": ship_to_info["address"]["street"],
            "street2": ship_to_info["address"]["addressInfo1"],
            "street3": None,
            "city": ship_to_info["address"]["city"],
            "state": delivery_address["state"],
            "postalCode": ship_to_info["address"]["zip"],
            "country": ship_to_info["address"]["countryCode"],
            "phone": ship_to_info["phone"]["phoneNumberPrefix"] + " " + ship_to_info["phone"]["phoneNumber"],
            "residential": False
        }

        insurance_options = None
        internationalOptions = None
        advanced_options = None
        test_label = True

        body = {
            "carrierCode": carrier_code,
            "serviceCode": service_code,
            "packageCode": package_code,
            "confirmation": confirmation,
            "shipDate": ship_date,
            "weight": weight,
            "dimensions": dimensions,
            "shipFrom": ship_from,
            "shipTo": ship_to,
            "insuranceOptions": insurance_options,
            "internationalOptions": internationalOptions,
            "advancedOptions": advanced_options,
            "testLabel": test_label
        }

        try:
            response_data = requests.post(
                url=url,
                auth=(self.api_id, self.api_password),
                headers=headers,
                data=json.dumps(body)
            )

            response_data = json.loads(response_data.text)
            # print(response_data)
            
            if 'shipmentId' in response_data:
                awb_number = ''
                tracking_response_data = response_data["trackingNumber"]
                if 'trackingData' in tracking_response_data:
                   for parcel in tracking_response_data['trackingData']['parcelList']:
                      if 'awbNumber' in parcel:
                         awb_number = parcel['awbNumber']
                return {
                  'service_provider': SHIPSTATION_PROVIDER,
                  'shipment_id': response_data['shipmentId'],
                  'carrier': carrier_code,
                  'carrier_service': service_code,
                  'shipment_amount': response_data["shipmentCost"],
                  'awb_number': awb_number,
               }
            elif 'Message' in response_data:
                frappe.throw(_('An Error occurred while creating Shipment: {0}')
                 .format(response_data['ExceptionMessage']))

        except Exception as e:
            print(f"에러 발생: {e}")

ERPNext에 shipstation API를 결합하여 shipment label을 생성하는 코드 작성

 

위와 같은 shipment에서 Fetch Shipping Rates를 클릭 시

선택 창이 나타남

성공 시 상태가 변경되고 shipment label이 생성됨