示例#1
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[Envelope]:
    packages = Packages(payload.parcels)
    product = Services(payload.services, Service).first

    request = create_envelope(body_content=GetEstimatedCharges(
        AuthenicateAccount=Authenticate(
            AccountID=settings.account_id,
            Password=settings.password,
        ),
        PkgInfo=PackgeInfoToGetCharges(
            Product=(product or Service.ics_courier_ground.value),
            Pieces=ArrayOfPieceInfo(PieceInfo=[
                PieceInfo(
                    Weight=piece.weight.value,
                    WeightUnit=piece.weight.unit,
                    Length=piece.length.value,
                    Width=piece.width.value,
                    Height=piece.height.value,
                    DeclaredValue=None,
                ) for piece in packages
            ]),
            FromPost=payload.shipper.postal_code,
            ToPost=payload.recipient.postal_code,
        )))

    return Serializable(request, lambda _: (product, Settings.serialize(_)))
示例#2
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[mailing_scenario]:
    """Create the appropriate Canada Post rate request depending on the destination

    :param settings: Purplship carrier connection settings
    :param payload: Purplship unified API rate request data
    :return: a domestic or international Canada post compatible request
    :raises: an OriginNotServicedError when origin country is not serviced by the carrier
    """
    if payload.shipper.country_code and payload.shipper.country_code != Country.CA.name:
        raise OriginNotServicedError(payload.shipper.country_code)

    package = Packages(payload.parcels, PackagePresets,
                       required=["weight"]).single
    services = Services(payload.services, ServiceType)
    options = Options(payload.options, OptionCode)

    request = mailing_scenario(
        customer_number=settings.customer_number,
        contract_id=None,
        promo_code=None,
        quote_type=None,
        expected_mailing_date=options.shipment_date,
        options=(optionsType(option=[
            optionType(option_code=getattr(option, 'key', option),
                       option_amount=getattr(option, 'value', None))
            for code, option in options if code in OptionCode
        ]) if any([c in OptionCode for c, _ in options]) else None),
        parcel_characteristics=parcel_characteristicsType(
            weight=package.weight.map(MeasurementOptions).KG,
            dimensions=dimensionsType(
                length=package.length.map(MeasurementOptions).CM,
                width=package.width.map(MeasurementOptions).CM,
                height=package.height.map(MeasurementOptions).CM,
            ),
            unpackaged=None,
            mailing_tube=None,
            oversized=None,
        ),
        services=(servicesType(
            service_code=[svc.value
                          for svc in services]) if any(services) else None),
        origin_postal_code=payload.shipper.postal_code,
        destination=destinationType(
            domestic=(
                domesticType(postal_code=payload.recipient.postal_code) if
                (payload.recipient.country_code == Country.CA.name) else None),
            united_states=(
                united_statesType(zip_code=payload.recipient.postal_code) if
                (payload.recipient.country_code == Country.US.name) else None),
            international=(internationalType(
                country_code=payload.recipient.postal_code) if
                           (payload.recipient.country_code not in [
                               Country.US.name, Country.CA.name
                           ]) else None),
        ),
    )

    return Serializable(request, _request_serializer)
示例#3
0
文件: intl.py 项目: iliaaz/purplship
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[IntlRateV2Request]:
    package = Packages(payload.parcels,
                       max_weight=Weight(70, WeightUnit.LB)).single
    services = Services(payload.options.keys(), RateService)
    extra_services = Services(payload.services, ExtraService)

    commercial = "Y" if "commercial" in services else "N"
    commercial_plus = "Y" if "plus" in services else "N"
    country = (Country[payload.recipient.country_code].value
               if payload.recipient.country_code else None)

    request = IntlRateV2Request(
        USERID=settings.username,
        Revision="2",
        Package=[
            PackageType(
                ID=0,
                Pounds=package.weight.LB,
                Ounces=package.weight.OZ,
                Machinable=("usps_machinable" in payload.options),
                MailType=IntlPackageType[package.packaging_type
                                         or "package"].value,
                GXG=None,
                ValueOfContents=None,
                Country=country,
                Width=package.width.IN,
                Length=package.length.IN,
                Height=package.height.IN,
                Girth=(package.girth.value
                       if package.packaging_type == "tube" else None),
                OriginZip=payload.shipper.postal_code,
                CommercialFlag=commercial,
                CommercialPlusFlag=commercial_plus,
                AcceptanceDateTime=datetime.today().strftime(
                    "%Y-%m-%dT%H:%M:%S"),
                DestinationPostalCode=payload.recipient.postal_code,
                ExtraServices=ExtraServicesType(
                    ExtraService=[s.value for s in extra_services]),
                Content=None,
            )
        ],
    )

    return Serializable(request, XP.export)
示例#4
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[RateV4Request]:
    package = Packages(payload.parcels).single
    options = Options(payload.options)
    service = Services(payload.services,
                       RateService).first or RateService.usps_all
    special_services = Services(payload.options.keys(), SpecialService)

    request = RateV4Request(
        USERID=settings.username,
        Revision="2",
        Package=[
            PackageType(
                ID=0,
                Service=service.value,
                FirstClassMailType=FirstClassMailType[
                    package.packaging_type or "your_packaging"].value,
                ZipOrigination=payload.shipper.postal_code,
                ZipDestination=payload.recipient.postal_code,
                Pounds=package.weight.LB,
                Ounces=package.weight.OZ,
                Container=Container[package.packaging_type
                                    or "your_packaging"].value,
                Width=package.width.IN,
                Length=package.length.IN,
                Height=package.height.IN,
                Girth=package.girth.value,
                Value=None,
                AmountToCollect=options.cash_on_delivery,
                SpecialServices=SpecialServicesType(
                    SpecialService=[s.value for s in special_services]),
                Content=None,
                GroundOnly=None,
                SortBy=None,
                Machinable=("usps_machinable" in options),
                ReturnLocations=None,
                ReturnServiceInfo=None,
                DropOffTime=None,
                ShipDate=ShipDateType(
                    valueOf_=str(datetime.today().strftime("%Y-%m-%d"))),
            )
        ],
    )

    return Serializable(request, XP.export)
示例#5
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[DicomRateRequest]:
    packages = Packages(payload.parcels)
    service = (Services(payload.services, Service).first
               or Service.dicom_ground_delivery).value
    options = Options(payload.options, Option)

    request = DicomRateRequest(
        category="Parcel",
        paymentType=PaymentType.prepaid.value,
        deliveryType=service,
        unitOfMeasurement=UnitOfMeasurement.KC.value,
        sender=Address(postalCode=payload.shipper.postal_code,
                       provinceCode=payload.shipper.state_code,
                       countryCode=payload.shipper.country_code,
                       name=(payload.shipper.company_name
                             or payload.shipper.person_name)),
        consignee=Address(postalCode=payload.recipient.postal_code,
                          provinceCode=payload.recipient.state_code,
                          countryCode=payload.recipient.country_code,
                          name=(payload.recipient.company_name
                                or payload.recipient.person_name)),
        parcels=[
            Parcel(
                quantity=1,
                parcelType=ParcelType[package.packaging_type
                                      or "dicom_box"].value,
                id=None,
                weight=package.weight.KG,
                length=package.height.CM,
                depth=package.length.CM,
                width=package.width.CM,
                note=None,
                status=None,
                FCA_Class=None,
                hazmat=None,
                requestReturnLabel=None,
                returnWaybill=None,
            ) for package in packages
        ],
        billing=settings.billing_account,
        promoCodes=None,
        surcharges=[
            Surcharge(type=getattr(option, 'key', option),
                      value=getattr(option, 'value', None))
            for _, option in options
        ],
        appointment=None,
    )

    return Serializable(request, DP.to_dict)
示例#6
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[priceRequest]:
    options = Options(payload.options, ShipmentOption)
    package = Packages(payload.parcels).single
    service = Services(payload.services, ShipmentService).first

    option_codes = [code for label, code in options if 'division' not in label]

    request = priceRequest(
        appId=settings.username,
        appVersion="3.0",
        priceCheck=priceCheck(
            rateId=None,
            sender=address(country=payload.shipper.country_code,
                           town=payload.shipper.city,
                           postcode=payload.shipper.postal_code),
            delivery=address(country=payload.recipient.country_code,
                             town=payload.recipient.city,
                             postcode=payload.recipient.postal_code),
            collectionDateTime=DF.fdatetime(options.shipment_date,
                                            output_format='%Y-%m-%dT%H:%M:%S'),
            product=product(
                id=getattr(service, 'value', None),
                division=next(
                    (code for label, code in options if 'division' in label),
                    None),
                productDesc=None,
                type_=('D' if package.parcel.is_document else 'N'),
                options=(optionsType(
                    option=[option(optionCode=code) for code in option_codes])
                         if any(option_codes) else None)),
            account=(account(
                accountNumber=settings.account_number,
                accountCountry=settings.account_country_code,
            ) if any([settings.account_number, settings.account_country_code])
                     else None),
            insurance=(insurance(insuranceValue=options.insurance,
                                 goodsValue=options.insurance)
                       if options.insurance is not None else None),
            termsOfPayment=PaymentType.sender.value,
            currency=options.currency,
            priceBreakDown=True,
            consignmentDetails=consignmentDetails(
                totalWeight=package.weight.KG,
                totalVolume=package.volume.value,
                totalNumberOfPieces=1,
            ),
            pieceLine=None),
    )

    return Serializable(request, XP.to_xml)
示例#7
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[UPSRateRequest]:
    packages = Packages(payload.parcels, PackagePresets)
    is_document = all([parcel.is_document for parcel in payload.parcels])
    service = Services(payload.services, ServiceCode).first
    mps_packaging = PackagingType.ups_unknown.value if len(
        packages) > 1 else None

    request = UPSRateRequest(
        Request=RequestType(
            RequestOption=["Shop", "Rate"],
            SubVersion=None,
            TransactionReference=TransactionReferenceType(
                CustomerContext=payload.reference,
                TransactionIdentifier=getattr(payload, 'id', None)),
        ),
        PickupType=None,
        CustomerClassification=None,
        Shipment=ShipmentType(
            OriginRecordTransactionTimestamp=None,
            Shipper=ShipperType(
                Name=payload.shipper.company_name,
                ShipperNumber=settings.account_number,
                Address=ShipAddressType(
                    AddressLine=SF.concat_str(
                        payload.recipient.address_line1,
                        payload.recipient.address_line2,
                    ),
                    City=payload.shipper.city,
                    StateProvinceCode=payload.shipper.state_code,
                    PostalCode=payload.shipper.postal_code,
                    CountryCode=payload.shipper.country_code,
                ),
            ),
            ShipTo=ShipToType(
                Name=payload.recipient.company_name,
                Address=ShipToAddressType(
                    AddressLine=SF.concat_str(
                        payload.recipient.address_line1,
                        payload.recipient.address_line2,
                    ),
                    City=payload.recipient.city,
                    StateProvinceCode=payload.recipient.state_code,
                    PostalCode=payload.recipient.postal_code,
                    CountryCode=payload.recipient.country_code,
                    ResidentialAddressIndicator=None,
                ),
            ),
            ShipFrom=None,
            AlternateDeliveryAddress=None,
            ShipmentIndicationType=None,
            PaymentDetails=None,
            FRSPaymentInformation=None,
            FreightShipmentInformation=None,
            GoodsNotInFreeCirculationIndicator=None,
            Service=(UOMCodeDescriptionType(Code=service.value,
                                            Description=None)
                     if service is not None else None),
            NumOfPieces=None,  # Only required for Freight
            ShipmentTotalWeight=
            None,  # Only required for "timeintransit" requests
            DocumentsOnlyIndicator=("" if is_document else None),
            Package=[
                PackageType(
                    PackagingType=UOMCodeDescriptionType(
                        Code=(mps_packaging
                              or PackagingType[package.packaging_type
                                               or "your_packaging"].value),
                        Description=None,
                    ),
                    Dimensions=(DimensionsType(
                        UnitOfMeasurement=UOMCodeDescriptionType(
                            Code=package.dimension_unit.value,
                            Description=None),
                        Length=package.length.value,
                        Width=package.width.value,
                        Height=package.height.value,
                    ) if any([
                        package.length.value,
                        package.height.value,
                        package.width.value,
                    ]) else None),
                    DimWeight=None,
                    PackageWeight=PackageWeightType(
                        UnitOfMeasurement=UOMCodeDescriptionType(
                            Code=UPSWeightUnit[package.weight_unit.name].value,
                            Description=None,
                        ),
                        Weight=package.weight.value,
                    ) if package.weight.value else None,
                    Commodity=None,
                    PackageServiceOptions=None,
                    AdditionalHandlingIndicator=None,
                ) for package in packages
            ],
            ShipmentServiceOptions=None,
            ShipmentRatingOptions=ShipmentRatingOptionsType(
                NegotiatedRatesIndicator=""),
            InvoiceLineTotal=None,
            RatingMethodRequestedIndicator=None,
            TaxInformationIndicator=None,
            PromotionalDiscountInformation=None,
            DeliveryTimeInformation=TimeInTransitRequestType(
                PackageBillType="02" if is_document else "03"),
        ),
    )
    return Serializable(
        create_envelope(header_content=settings.Security,
                        body_content=request),
        _request_serializer,
    )
示例#8
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[RateV4Request]:
    """Create the appropriate USPS rate request depending on the destination

    :param payload: Purplship unified API rate request data
    :param settings: USPS connection and auth settings
    :return: a domestic or international USPS compatible request
    :raises: an OriginNotServicedError when origin country is not serviced by the carrier
    """

    if payload.shipper.country_code is not None and payload.shipper.country_code != Country.US.name:
        raise OriginNotServicedError(payload.shipper.country_code)

    if payload.recipient.country_code is not None and payload.recipient.country_code == Country.US.name:
        raise DestinationNotServicedError(payload.recipient.country_code)

    package = Packages(payload.parcels).single
    options = Options(payload.options, ShipmentOption)
    service = (Services(payload.services, ShipmentService).first
               or ShipmentService.usps_all)
    special_services = [
        getattr(option, 'value', option) for key, option in options
        if 'usps_option' not in key
    ]
    insurance = next(
        (option.value for key, option in options if 'usps_insurance' in key),
        options.insurance)

    container = PackagingType[package.packaging_type or "your_packaging"]
    sort_level = (SortLevelType[container.name].value
                  if service.value in ["All", "Online"] else None)
    mail_type = (FirstClassMailType[container.name].value
                 if 'first_class' in service.value else None)

    request = RateV4Request(
        USERID=settings.username,
        Revision="2",
        Package=[
            PackageType(
                ID=0,
                Service=service.value,
                FirstClassMailType=mail_type,
                ZipOrigination=payload.shipper.postal_code,
                ZipDestination=payload.recipient.postal_code,
                Pounds=package.weight.LB,
                Ounces=package.weight.OZ,
                Container=container.value,
                Width=package.width.IN,
                Length=package.length.IN,
                Height=package.height.IN,
                Girth=package.girth.value,
                Value=insurance,
                AmountToCollect=options.cash_on_delivery,
                SpecialServices=(SpecialServicesType(
                    SpecialService=[s for s in special_services])
                                 if any(special_services) else None),
                Content=None,
                GroundOnly=options.usps_option_ground_only,
                SortBy=sort_level,
                Machinable=(options.usps_option_machinable_item or False),
                ReturnLocations=options.usps_option_return_service_info,
                ReturnServiceInfo=options.usps_option_return_service_info,
                DropOffTime=('13:30'
                             if options.shipment_date is not None else None),
                ShipDate=(ShipDateType(
                    valueOf_=DF.fdate(options.shipment_date))
                          if options.shipment_date is not None else None),
            )
        ],
    )

    return Serializable(request, XP.export)
示例#9
0
def rate_request(payload: RateRequest, settings: Settings) -> Serializable[IntlRateV2Request]:
    """Create the appropriate USPS International rate request depending on the destination

    :param payload: Purplship unified API rate request data
    :param settings: USPS International connection and auth settings
    :return: a domestic or international USPS International compatible request
    :raises:
        - OriginNotServicedError when origin country is not serviced by the carrier
        - DestinationNotServicedError when destination country is US
    """

    if payload.shipper.country_code is not None and payload.shipper.country_code != Country.US.name:
        raise OriginNotServicedError(payload.shipper.country_code)

    if payload.recipient.country_code == Country.US.name:
        raise DestinationNotServicedError(payload.recipient.country_code)

    package = Packages(payload.parcels, max_weight=Weight(70, WeightUnit.LB)).single
    options = Options(payload.options, ShipmentOption)
    services = Services(payload.services, ShipmentService)

    extra_services = [getattr(option, 'value', option) for key, option in options if 'usps_option' not in key]
    commercial = next(("Y" for svc in services if "commercial" in svc.name), "N")
    commercial_plus = next(("Y" for svc in services if "plus" in svc.name), "N")
    country = (
        Country[payload.recipient.country_code].value
        if payload.recipient.country_code else None
    )

    request = IntlRateV2Request(
        USERID=settings.username,
        Revision="2",
        Package=[
            PackageType(
                ID=0,
                Pounds=package.weight.LB,
                Ounces=package.weight.OZ,
                Machinable=options["usps_option_machinable_item"],
                MailType=PackagingType[package.packaging_type or "package"].value,
                GXG=None,
                ValueOfContents=None,
                Country=country,
                Width=package.width.IN,
                Length=package.length.IN,
                Height=package.height.IN,
                Girth=(package.girth.value if package.packaging_type == "tube" else None),
                OriginZip=payload.shipper.postal_code,
                CommercialFlag=commercial,
                CommercialPlusFlag=commercial_plus,
                AcceptanceDateTime=datetime.today().strftime("%Y-%m-%dT%H:%M:%S"),
                DestinationPostalCode=payload.recipient.postal_code,
                ExtraServices=(
                    ExtraServicesType(
                        ExtraService=[
                            getattr(option, 'value', option)
                            for option in extra_services
                        ]
                    ) if any(extra_services) else None
                ),
                Content=None,
            )
        ],
    )

    return Serializable(request, XP.export)
示例#10
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[DCTRequest]:
    packages = Packages(payload.parcels, PackagePresets, required=["weight"])
    products = [*Services(payload.services, ProductCode)]
    options = Options(payload.options, SpecialServiceCode)

    is_international = payload.shipper.country_code != payload.recipient.country_code
    is_document = all([parcel.is_document for parcel in payload.parcels])
    is_dutiable = not is_document

    if not is_international and payload.shipper.country_code in ["CA"]:
        raise DestinationNotServicedError(payload.shipper.country_code)

    paperless = (SpecialServiceCode.dhl_paperless_trade if
                 (is_international and is_dutiable) else None)
    special_services = [
        *options, *([(paperless.name, None)] if paperless is not None else [])
    ]
    insurance = options[
        'dhl_shipment_insurance'].value if 'dhl_shipment_insurance' in options else None

    if len(products) == 0:
        if is_international and is_document:
            product = 'dhl_express_worldwide_doc'
        elif is_international:
            product = 'dhl_express_worldwide_nondoc'
        elif is_document:
            product = 'dhl_express_worldwide_doc'
        else:
            product = 'dhl_express_easy_nondoc'

        products = [ProductCode[product]]

    request = DCTRequest(GetQuote=GetQuoteType(
        Request=settings.Request(
            MetaData=MetaData(SoftwareName="3PV", SoftwareVersion=1.0)),
        From=DCTFrom(
            CountryCode=payload.shipper.country_code,
            Postalcode=payload.shipper.postal_code,
            City=payload.shipper.city,
            Suburb=payload.shipper.state_code,
        ),
        To=DCTTo(
            CountryCode=payload.recipient.country_code,
            Postalcode=payload.recipient.postal_code,
            City=payload.recipient.city,
            Suburb=payload.recipient.state_code,
        ),
        BkgDetails=BkgDetailsType(
            PaymentCountryCode=payload.shipper.country_code,
            NetworkTypeCode=NetworkType.both_time_and_day_definite.value,
            WeightUnit=WeightUnit.LB.value,
            DimensionUnit=DimensionUnit.IN.value,
            ReadyTime=time.strftime("PT%HH%MM"),
            Date=time.strftime("%Y-%m-%d"),
            IsDutiable=("Y" if is_dutiable else "N"),
            Pieces=PiecesType(Piece=[
                PieceType(
                    PieceID=package.parcel.id or f"{index}",
                    PackageTypeCode=DCTPackageType[package.packaging_type
                                                   or "your_packaging"].value,
                    Depth=package.length.IN,
                    Width=package.width.IN,
                    Height=package.height.IN,
                    Weight=package.weight.LB,
                ) for index, package in enumerate(
                    cast(Iterable[Package], packages), 1)
            ]),
            NumberOfPieces=len(packages),
            ShipmentWeight=packages.weight.LB,
            Volume=None,
            PaymentAccountNumber=settings.account_number,
            InsuredCurrency=(options.currency
                             if insurance is not None else None),
            InsuredValue=insurance,
            PaymentType=None,
            AcctPickupCloseTime=None,
            QtdShp=[
                QtdShpType(
                    GlobalProductCode=product.value,
                    LocalProductCode=product.value,
                    QtdShpExChrg=[
                        QtdShpExChrgType(
                            SpecialServiceType=SpecialServiceCode[key].value.
                            key) for key, _ in special_services
                        if key in SpecialServiceCode
                    ],
                ) for product in products
            ],
        ),
        Dutiable=(DCTDutiable(
            DeclaredValue=insurance or 1.0,
            DeclaredCurrency=options.currency
            or CountryCurrency[payload.shipper.country_code].value)
                  if is_international and is_dutiable else None),
    ), )

    return Serializable(request, _request_serializer)
示例#11
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[Envelope]:
    packages = Packages(payload.parcels)
    service_type = Services(payload.services, Service).first
    options = Options(payload.options, Option)

    shipment_date = DF.fdatetime(options.shipment_date
                                 or time.strftime('%Y-%m-%d'),
                                 current_format='%Y-%m-%d',
                                 output_format='%Y-%m-%dT%H:%M:%S')
    premium: Optional[bool] = next((True
                                    for option, _ in options if option in [
                                        Option.canpar_ten_am.name,
                                        Option.canpar_noon.name,
                                        Option.canpar_saturday.name,
                                    ]), None)
    nsr = next(
        (Option[o].value for o in
         ['canpar_no_signature_required', 'canpar_not_no_signature_required']
         if o in options), None)

    request = create_envelope(body_content=rateShipment(request=RateShipmentRq(
        apply_association_discount=False,
        apply_individual_discount=False,
        apply_invoice_discount=False,
        password=settings.password,
        shipment=Shipment(
            cod_type=options['canpar_cash_on_delivery'],
            delivery_address=Address(
                address_line_1=payload.recipient.address_line1,
                address_line_2=payload.recipient.address_line2,
                address_line_3=None,
                attention=payload.recipient.person_name,
                city=payload.recipient.city,
                country=payload.recipient.country_code,
                email=payload.recipient.email,
                extension=None,
                name=payload.recipient.company_name,
                phone=payload.recipient.phone_number,
                postal_code=payload.recipient.postal_code,
                province=payload.recipient.state_code,
                residential=payload.recipient.residential,
            ),
            description=None,
            dg=options['canpar_dangerous_goods'],
            dimention_unit=DimensionUnit.IN.value,
            handling=None,
            handling_type=None,
            instruction=None,
            nsr=nsr,
            packages=[
                Package(alternative_reference=None,
                        cod=None,
                        cost_centre=None,
                        declared_value=None,
                        height=pkg.height.CM,
                        length=pkg.length.CM,
                        lg=None,
                        reference=None,
                        reported_weight=pkg.weight.LB,
                        store_num=None,
                        width=pkg.width.CM,
                        xc=options['canpar_extra_care']) for pkg in packages
            ],
            pickup_address=Address(
                address_line_1=payload.shipper.address_line1,
                address_line_2=payload.shipper.address_line2,
                address_line_3=None,
                attention=payload.shipper.person_name,
                city=payload.shipper.city,
                country=payload.shipper.country_code,
                email=payload.shipper.email,
                extension=None,
                name=payload.shipper.company_name,
                phone=payload.shipper.phone_number,
                postal_code=payload.shipper.postal_code,
                province=payload.shipper.state_code,
                residential=payload.shipper.residential,
            ),
            premium=premium,
            proforma=None,
            reported_weight_unit=WeightUnit.LB.value,
            send_email_to_delivery=payload.recipient.email,
            send_email_to_pickup=payload.shipper.email,
            service_type=service_type.value,
            shipper_num=None,
            shipping_date=shipment_date,
            subtotal=None,
            subtotal_with_handling=None,
            total=None,
            total_with_handling=None,
            user_id=None,
        ),
        user_id=settings.username)))

    return Serializable(
        request,
        partial(
            settings.serialize,
            extra_namespace='xmlns:xsd1="http://dto.canshipws.canpar.com/xsd"',
            special_prefixes=dict(shipment_children='xsd1')))
示例#12
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[Envelope]:
    packages = Packages(payload.parcels, PackagePresets, required=["weight"])
    service = Services(payload.services, Product).first
    options = Options(payload.options, Service)

    package_description = packages[0].parcel.description if len(
        packages) == 1 else None
    is_document = all([parcel.is_document for parcel in payload.parcels])
    shipper_phone = Phone(payload.shipper.phone_number,
                          payload.shipper.country_code or 'CA')
    recipient_phone = Phone(payload.recipient.phone_number,
                            payload.recipient.country_code)
    is_international = payload.shipper.country_code != payload.recipient.country_code
    option_ids = [(key, value) for key, value in options
                  if key in Service and key not in NON_OFFICIAL_SERVICES]

    # When no specific service is requested, set a default one.
    if service is None:
        show_alternate_services = options[
            'purolator_show_alternative_services'] is not False
        service = Product['purolator_express_international'
                          if is_international else 'purolator_express']
    else:
        show_alternate_services = options[
            'purolator_show_alternative_services'] is True

    request = create_envelope(
        header_content=RequestContext(
            Version="2.1",
            Language=settings.language,
            GroupID="",
            RequestReference=getattr(payload, 'id', ""),
            UserToken=settings.user_token,
        ),
        body_content=GetFullEstimateRequest(
            Shipment=Shipment(
                SenderInformation=SenderInformation(
                    Address=Address(
                        Name=payload.shipper.person_name or "",
                        Company=payload.shipper.company_name,
                        Department=None,
                        StreetNumber="",
                        StreetSuffix=None,
                        StreetName=SF.concat_str(payload.shipper.address_line1,
                                                 join=True),
                        StreetType=None,
                        StreetDirection=None,
                        Suite=None,
                        Floor=None,
                        StreetAddress2=SF.concat_str(
                            payload.shipper.address_line2, join=True),
                        StreetAddress3=None,
                        City=payload.shipper.city or "",
                        Province=payload.shipper.state_code or "",
                        Country=payload.shipper.country_code or "",
                        PostalCode=payload.shipper.postal_code or "",
                        PhoneNumber=PhoneNumber(
                            CountryCode=shipper_phone.country_code or "0",
                            AreaCode=shipper_phone.area_code or "0",
                            Phone=shipper_phone.phone or "0",
                            Extension=None,
                        ),
                        FaxNumber=None,
                    ),
                    TaxNumber=(payload.shipper.federal_tax_id
                               or payload.shipper.state_tax_id),
                ),
                ReceiverInformation=ReceiverInformation(
                    Address=Address(
                        Name=payload.recipient.person_name or "",
                        Company=payload.recipient.company_name,
                        Department=None,
                        StreetNumber="",
                        StreetSuffix=None,
                        StreetName=SF.concat_str(
                            payload.recipient.address_line1, join=True),
                        StreetType=None,
                        StreetDirection=None,
                        Suite=None,
                        Floor=None,
                        StreetAddress2=SF.concat_str(
                            payload.recipient.address_line2, join=True),
                        StreetAddress3=None,
                        City=payload.recipient.city or "",
                        Province=payload.recipient.state_code or "",
                        Country=payload.recipient.country_code or "",
                        PostalCode=payload.recipient.postal_code or "",
                        PhoneNumber=PhoneNumber(
                            CountryCode=recipient_phone.country_code or "0",
                            AreaCode=recipient_phone.area_code or "0",
                            Phone=recipient_phone.phone or "0",
                            Extension=None,
                        ),
                        FaxNumber=None,
                    ),
                    TaxNumber=(payload.recipient.federal_tax_id
                               or payload.recipient.state_tax_id),
                ),
                FromOnLabelIndicator=None,
                FromOnLabelInformation=None,
                ShipmentDate=options.shipment_date,
                PackageInformation=PackageInformation(
                    ServiceID=service.value,
                    Description=package_description,
                    TotalWeight=(TotalWeight(
                        Value=packages.weight.map(MeasurementOptions).LB,
                        WeightUnit=PurolatorWeightUnit.LB.value,
                    ) if packages.weight.value is not None else None),
                    TotalPieces=1,
                    PiecesInformation=ArrayOfPiece(Piece=[
                        Piece(
                            Weight=(PurolatorWeight(
                                Value=package.weight.map(MeasurementOptions).
                                value,
                                WeightUnit=PurolatorWeightUnit[
                                    package.weight_unit.value].value,
                            ) if package.weight.value else None),
                            Length=(PurolatorDimension(
                                Value=package.length.value,
                                DimensionUnit=PurolatorDimensionUnit[
                                    package.dimension_unit.value].value,
                            ) if package.length.value else None),
                            Width=(PurolatorDimension(
                                Value=package.width.value,
                                DimensionUnit=PurolatorDimensionUnit[
                                    package.dimension_unit.value].value,
                            ) if package.width.value else None),
                            Height=(PurolatorDimension(
                                Value=package.height.value,
                                DimensionUnit=PurolatorDimensionUnit[
                                    package.dimension_unit.value].value,
                            ) if package.height.value else None),
                            Options=ArrayOfOptionIDValuePair(
                                OptionIDValuePair=[
                                    OptionIDValuePair(ID=key, Value=value)
                                    for key, value in option_ids
                                ]) if any(option_ids) else None,
                        ) for package in packages
                    ]),
                    DangerousGoodsDeclarationDocumentIndicator=None,
                    OptionsInformation=None,
                ),
                InternationalInformation=(InternationalInformation(
                    DocumentsOnlyIndicator=is_document,
                    ContentDetails=None,
                    BuyerInformation=None,
                    PreferredCustomsBroker=None,
                    DutyInformation=DutyInformation(
                        BillDutiesToParty=DutyPaymentType.recipient.value,
                        BusinessRelationship=BusinessRelationship.NOT_RELATED.
                        value,
                        Currency=options.currency,
                    ),
                    ImportExportType=None,
                    CustomsInvoiceDocumentIndicator=None,
                ) if is_international else None),
                ReturnShipmentInformation=None,
                PaymentInformation=PaymentInformation(
                    PaymentType=PaymentType.SENDER.value,
                    RegisteredAccountNumber=settings.account_number,
                ),
                PickupInformation=PickupInformation(
                    PickupType=PickupType.DROP_OFF.value),
                NotificationInformation=None,
                TrackingReferenceInformation=(TrackingReferenceInformation(
                    Reference1=payload.reference) if payload.reference != ""
                                              else None),
                OtherInformation=None,
                ProactiveNotification=None,
            ),
            ShowAlternativeServicesIndicator=show_alternate_services,
        ),
    )
    return Serializable(request, standard_request_serializer)
示例#13
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[FedexRateRequest]:
    packages = Packages(payload.parcels, PackagePresets, required=["weight"])
    service = Services(payload.services, ServiceType).first
    options = Options(payload.options)

    package_type = (PackagingType[packages[0].packaging_type
                                  or "your_packaging"].value
                    if len(packages) == 1 else None)
    request_types = ["LIST"
                     ] + ([] if "currency" not in options else ["PREFERRED"])

    request = FedexRateRequest(
        WebAuthenticationDetail=settings.webAuthenticationDetail,
        ClientDetail=settings.clientDetail,
        TransactionDetail=TransactionDetail(CustomerTransactionId="FTC"),
        Version=VersionId(ServiceId="crs", Major=26, Intermediate=0, Minor=0),
        ReturnTransitAndCommit=True,
        CarrierCodes=None,
        VariableOptions=None,
        ConsolidationKey=None,
        RequestedShipment=RequestedShipment(
            ShipTimestamp=DF.date(options.shipment_date or datetime.now()),
            DropoffType="REGULAR_PICKUP",
            ServiceType=(service.value if service is not None else None),
            PackagingType=package_type,
            VariationOptions=None,
            TotalWeight=FedexWeight(
                Units=WeightUnit.LB.value,
                Value=packages.weight.LB,
            ),
            TotalInsuredValue=None,
            PreferredCurrency=options.currency,
            ShipmentAuthorizationDetail=None,
            Shipper=Party(
                AccountNumber=settings.account_number,
                Tins=([
                    TaxpayerIdentification(TinType=None, Number=tax)
                    for tax in [
                        payload.shipper.federal_tax_id,
                        payload.shipper.state_tax_id,
                    ]
                ] if any([
                    payload.shipper.federal_tax_id,
                    payload.shipper.state_tax_id
                ]) else None),
                Contact=Contact(
                    ContactId=None,
                    PersonName=payload.shipper.person_name,
                    Title=None,
                    CompanyName=payload.shipper.company_name,
                    PhoneNumber=payload.shipper.phone_number,
                    PhoneExtension=None,
                    TollFreePhoneNumber=None,
                    PagerNumber=None,
                    FaxNumber=None,
                    EMailAddress=payload.shipper.email,
                ) if any((
                    payload.shipper.company_name,
                    payload.shipper.person_name,
                    payload.shipper.phone_number,
                    payload.shipper.email,
                )) else None,
                Address=Address(
                    StreetLines=SF.concat_str(payload.shipper.address_line1,
                                              payload.shipper.address_line2),
                    City=payload.shipper.city,
                    StateOrProvinceCode=payload.shipper.state_code,
                    PostalCode=payload.shipper.postal_code,
                    UrbanizationCode=None,
                    CountryCode=payload.shipper.country_code,
                    CountryName=None,
                    Residential=None,
                    GeographicCoordinates=None,
                ),
            ),
            Recipient=Party(
                AccountNumber=None,
                Tins=[
                    TaxpayerIdentification(TinType=None, Number=tax)
                    for tax in [
                        payload.recipient.federal_tax_id,
                        payload.recipient.state_tax_id,
                    ]
                ] if any([
                    payload.recipient.federal_tax_id,
                    payload.recipient.state_tax_id
                ]) else None,
                Contact=Contact(
                    ContactId=None,
                    PersonName=payload.recipient.person_name,
                    Title=None,
                    CompanyName=payload.recipient.company_name,
                    PhoneNumber=payload.recipient.phone_number,
                    PhoneExtension=None,
                    TollFreePhoneNumber=None,
                    PagerNumber=None,
                    FaxNumber=None,
                    EMailAddress=payload.recipient.email,
                ) if any((
                    payload.recipient.company_name,
                    payload.recipient.person_name,
                    payload.recipient.phone_number,
                    payload.recipient.email,
                )) else None,
                Address=Address(
                    StreetLines=SF.concat_str(
                        payload.recipient.address_line1,
                        payload.recipient.address_line2,
                    ),
                    City=payload.recipient.city,
                    StateOrProvinceCode=payload.recipient.state_code,
                    PostalCode=payload.recipient.postal_code,
                    UrbanizationCode=None,
                    CountryCode=payload.recipient.country_code,
                    CountryName=None,
                    Residential=None,
                    GeographicCoordinates=None,
                ),
            ),
            RecipientLocationNumber=None,
            Origin=None,
            SoldTo=None,
            ShippingChargesPayment=None,
            SpecialServicesRequested=None,
            ExpressFreightDetail=None,
            FreightShipmentDetail=None,
            DeliveryInstructions=None,
            VariableHandlingChargeDetail=None,
            CustomsClearanceDetail=None,
            PickupDetail=None,
            SmartPostDetail=None,
            BlockInsightVisibility=None,
            LabelSpecification=None,
            ShippingDocumentSpecification=None,
            RateRequestTypes=request_types,
            EdtRequestType=None,
            PackageCount=len(packages),
            ShipmentOnlyFields=None,
            ConfigurationData=None,
            RequestedPackageLineItems=[
                RequestedPackageLineItem(
                    SequenceNumber=index,
                    GroupNumber=None,
                    GroupPackageCount=1,
                    VariableHandlingChargeDetail=None,
                    InsuredValue=None,
                    Weight=FedexWeight(
                        Units=package.weight_unit.value,
                        Value=package.weight.value,
                    ) if package.weight.value is not None else None,
                    Dimensions=Dimensions(
                        Length=package.length.value,
                        Width=package.width.value,
                        Height=package.height.value,
                        Units=package.dimension_unit.value,
                    ) if any([
                        package.length.value,
                        package.width.value,
                        package.height.value,
                    ]) else None,
                    PhysicalPackaging=None,
                    ItemDescription=package.parcel.description,
                    ItemDescriptionForClearance=None,
                    CustomerReferences=None,
                    SpecialServicesRequested=None,
                    ContentRecords=None,
                ) for index, package in enumerate(packages, 1)
            ],
        ),
    )
    return Serializable(request, _request_serializer)
示例#14
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[Envelope]:
    packages = Packages(payload.parcels, PackagePresets)
    packages.validate(required=["weight"])
    options = Options(payload.options, ServiceOption)
    service = Services(payload.services, ServiceCode).first
    ship_from = CompleteAddress.map(payload.shipper)
    ship_to = CompleteAddress.map(payload.shipper)

    mps_packaging = PackagingType.ups_freight_other.value if len(
        packages) > 1 else None

    request = create_envelope(
        header_content=settings.Security,
        body_content=FreightRateRequest(
            Request=RequestType(
                RequestOption=[1],
                SubVersion=1707,
                TransactionReference=TransactionReferenceType(
                    CustomerContext=payload.reference,
                    TransactionIdentifier=getattr(payload, "id", None),
                ),
            ),
            ShipFrom=ShipFromType(
                Name=ship_from.company_name,
                Address=AddressType(
                    AddressLine=[ship_from.address_line],
                    City=ship_from.city,
                    StateProvinceCode=ship_from.state_code,
                    Town=None,
                    CountryCode=ship_from.country_code,
                    ResidentialAddressIndicator=("" if ship_from.residential
                                                 else None),
                ),
                AttentionName=ship_from.person_name,
                TariffPoint=None,
            ),
            ShipTo=ShipToType(
                Name=ship_to.company_name,
                Address=AddressType(
                    AddressLine=[ship_to.address_line],
                    City=ship_to.city,
                    StateProvinceCode=ship_to.state_code,
                    Town=None,
                    CountryCode=ship_to.country_code,
                    ResidentialAddressIndicator=("" if ship_to.residential else
                                                 None),
                ),
                AttentionName=ship_to.person_name,
                TariffPoint=None,
            ),
            PaymentInformation=PaymentInformationType(
                Payer=PayerType(
                    Name=ship_from.company_name,
                    Address=AddressType(
                        AddressLine=[ship_from.address_line],
                        City=ship_from.city,
                        StateProvinceCode=ship_from.state_code,
                        Town=None,
                        CountryCode=ship_from.country_code,
                        ResidentialAddressIndicator=(
                            "" if ship_from.residential else None),
                    ),
                    AttentionName=ship_from.person_name,
                    ShipperNumber=settings.account_number,
                ),
                ShipmentBillingOption=RateCodeDescriptionType(
                    Code=40, Description="Freight Collect"),
            ),
            Service=(RateCodeDescriptionType(Code=service, Description=None)
                     if service is not None else None),
            HandlingUnitOne=None,
            HandlingUnitTwo=None,
            Commodity=[
                CommodityType(
                    CommodityID=getattr(commodity, "id", None),
                    Description=commodity.parcel.description,
                    Weight=WeightType(
                        Value=commodity.weight.value,
                        UnitOfMeasurement=UnitOfMeasurementType(
                            Code=UPSWeightUnit[
                                commodity.weight_unit.name].value, ),
                    ),
                    AdjustedWeight=None,
                    Dimensions=(DimensionsType(
                        UnitOfMeasurement=UnitOfMeasurementType(
                            Code=commodity.dimension_unit.value,
                            Description=None),
                        Length=commodity.length.value,
                        Width=commodity.width.value,
                        Height=commodity.height.value,
                    ) if commodity.has_dimensions else None),
                    NumberOfPieces=1,
                    PackagingType=RateCodeDescriptionType(
                        Code=(mps_packaging or PackagingType[
                            commodity.packaging_type or "small_box"].value, )),
                    DangerousGoodsIndicator=None,
                    CommodityValue=None,
                    FreightClass=None,
                    NMFCCommodity=None,
                    NMFCCommodityCode=None,
                ) for commodity in packages
            ],
            ShipmentServiceOptions=(ShipmentServiceOptionsType(
                PickupOptions=None,
                DeliveryOptions=None,
                OverSeasLeg=None,
                COD=None,
                DangerousGoods=None,
                SortingAndSegregating=None,
                DeclaredValue=None,
                ExcessDeclaredValue=None,
                CustomsValue=None,
                DeliveryDutiesPaidIndicator=None,
                DeliveryDutiesUnpaidIndicator=None,
                HandlingCharge=None,
                CustomsClearanceIndicator=None,
                FreezableProtectionIndicator=None,
                ExtremeLengthIndicator=None,
                LinearFeet=None,
                AdjustedHeight=None,
            ) if any([
                options.cash_on_delivery,
                options.email_notification,
                options.dangerous_good,
                options.declared_value,
            ]) else None),
            PickupRequest=None,
            AlternateRateOptions=RateCodeDescriptionType(Code=3),
            GFPOptions=None,
            AccountType=None,
            ShipmentTotalWeight=ShipmentTotalWeightType(
                Value=packages.weight.value,
                UnitOfMeasurement=UnitOfMeasurementType(
                    Code=UPSWeightUnit[packages.weight.unit].value, ),
            ),
            HandlingUnitWeight=None,
            AdjustedWeightIndicator=None,
            TimeInTransitIndicator="",
            HandlingUnits=None,
            AdjustedHeightIndicator=None,
            DensityEligibleIndicator=None,
            QuoteNumberIndicator="",
        ),
    )

    return Serializable(request, _request_serializer)
示例#15
0
def quote_request(payload: RateRequest, settings: Settings) -> Serializable[EShipper]:
    options = Options(payload.options, Option)
    packages = Packages(payload.parcels, required=["weight", "height", "width", "length"])
    packaging_type = PackagingType[packages.package_type or "eshipper_boxes"].value
    packaging = ("Pallet" if packaging_type in [PackagingType.pallet.value] else "Package")
    service = (Services(payload.services, Service).first or Service.eshipper_all)

    freight_class = next(
        (FreightClass[c].value for c in payload.options.keys() if c in FreightClass),
        None,
    )

    request = EShipper(
        username=settings.username,
        password=settings.password,
        version="3.0.0",
        QuoteRequest=QuoteRequestType(
            saturdayPickupRequired=options.eshipper_saturday_pickup_required,
            homelandSecurity=options.eshipper_homeland_security,
            pierCharge=None,
            exhibitionConventionSite=options.eshipper_exhibition_convention_site,
            militaryBaseDelivery=options.eshipper_military_base_delivery,
            customsIn_bondFreight=options.eshipper_customs_in_bond_freight,
            limitedAccess=options.eshipper_limited_access,
            excessLength=options.eshipper_excess_length,
            tailgatePickup=options.eshipper_tailgate_pickup,
            residentialPickup=options.eshipper_residential_pickup,
            crossBorderFee=None,
            notifyRecipient=options.eshipper_notify_recipient,
            singleShipment=options.eshipper_single_shipment,
            tailgateDelivery=options.eshipper_tailgate_delivery,
            residentialDelivery=options.eshipper_residential_delivery,
            insuranceType=options.insurance is not None,
            scheduledShipDate=None,
            insideDelivery=options.eshipper_inside_delivery,
            isSaturdayService=options.eshipper_is_saturday_service,
            dangerousGoodsType=options.eshipper_dangerous_goods_type,
            serviceId=service.value,
            stackable=options.eshipper_stackable,
            From=FromType(
                id=payload.shipper.id,
                company=payload.shipper.company_name or " ",
                instructions=None,
                email=payload.shipper.email,
                attention=payload.shipper.person_name,
                phone=payload.shipper.phone_number,
                tailgateRequired=None,
                residential=payload.shipper.residential,
                address1=SF.concat_str(payload.shipper.address_line1, join=True),
                address2=SF.concat_str(payload.shipper.address_line2, join=True),
                city=payload.shipper.city,
                state=payload.shipper.state_code,
                zip=payload.shipper.postal_code,
                country=payload.shipper.country_code,
            ),
            To=ToType(
                id=payload.recipient.id,
                company=payload.recipient.company_name or " ",
                notifyRecipient=None,
                instructions=None,
                email=payload.recipient.email,
                attention=payload.recipient.person_name,
                phone=payload.recipient.phone_number,
                tailgateRequired=None,
                residential=payload.recipient.residential,
                address1=SF.concat_str(payload.recipient.address_line1, join=True),
                address2=SF.concat_str(payload.recipient.address_line2, join=True),
                city=payload.recipient.city,
                state=payload.recipient.state_code,
                zip=payload.recipient.postal_code,
                country=payload.recipient.country_code,
            ),
            COD=None,
            Packages=PackagesType(
                Package=[
                    PackageType(
                        length=ceil(package.length.IN),
                        width=ceil(package.width.IN),
                        height=ceil(package.height.IN),
                        weight=ceil(package.weight.LB),
                        type_=packaging_type,
                        freightClass=freight_class,
                        nmfcCode=None,
                        insuranceAmount=None,
                        codAmount=None,
                        description=package.parcel.description,
                    )
                    for package in packages
                ],
                type_=packaging,
            ),
        ),
    )

    return Serializable(request, standard_request_serializer)