Example #1
0
def _create_pickup_request(
    payload: PickupRequest, settings: Settings
) -> Serializable[Envelope]:
    packages = Packages(payload.parcels, PackagePresets)
    has_overweight = any(package for package in packages if package.weight.KG > 32)

    request = create_envelope(
        header_content=settings.Security,
        body_content=PickupCreationRequest(
            Request=RequestType(),
            RatePickupIndicator="N",
            TaxInformationIndicator=None,
            UserLevelDiscountIndicator=None,
            Shipper=ShipperType(
                Account=AccountType(
                    AccountNumber=settings.account_number,
                    AccountCountryCode=payload.address.country_code or "",
                ),
                ChargeCard=None,
                TaxInformation=None,
            ),
            PickupDateInfo=PickupDateInfoType(
                CloseTime=DF.ftime(payload.closing_time, "%H:%M", "%H%M"),
                ReadyTime=DF.ftime(payload.ready_time, "%H:%M", "%H%M"),
                PickupDate=DF.date(payload.pickup_date).strftime("%Y%m%d"),
            ),
            PickupAddress=PickupAddressType(
                CompanyName=payload.address.company_name,
                ContactName=payload.address.person_name,
                AddressLine=SF.concat_str(
                    payload.address.address_line1, payload.address.address_line2
                ),
                Room=None,
                Floor=None,
                City=payload.address.city,
                StateProvince=payload.address.state_code,
                Urbanization=None,
                PostalCode=payload.address.postal_code,
                CountryCode=payload.address.country_code,
                ResidentialIndicator=("Y" if payload.address.residential else "N"),
                PickupPoint=payload.package_location,
                Phone=PhoneType(Number=payload.address.phone_number, Extension=None)
                if payload.address.phone_number is not None
                else None,
            ),
            AlternateAddressIndicator="Y",
            PickupPiece=None,
            TotalWeight=WeightType(
                Weight=packages.weight.LB, UnitOfMeasurement=WeightUnit.LB.value
            ),
            OverweightIndicator=("Y" if has_overweight else "N"),
            TrackingData=None,
            TrackingDataWithReferenceNumber=None,
            PaymentMethod="01",
            SpecialInstruction=payload.instruction,
            ReferenceNumber=None,
            FreightOptions=None,
            ServiceCategory=None,
            CashType=None,
            ShippingLabelsAvailable="Y",
        ),
    )

    return Serializable(
        request,
        default_request_serializer(
            "v11", 'xmlns:v11="http://www.ups.com/XMLSchema/XOLTWS/Pickup/v1.1"'
        ),
    )
Example #2
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)
Example #3
0
def _pickup_request(payload: PickupRequest,
                    settings: Settings) -> Serializable[CreatePickupRequest]:
    same_day = DF.date(payload.pickup_date).date() == datetime.today().date()
    packages = Packages(payload.parcels, PackagePresets, required=["weight"])

    request = CreatePickupRequest(
        WebAuthenticationDetail=settings.webAuthenticationDetail,
        ClientDetail=settings.clientDetail,
        TransactionDetail=TransactionDetail(CustomerTransactionId="FTC"),
        Version=VersionId(ServiceId="disp", Major=22, Intermediate=0, Minor=0),
        AssociatedAccountNumber=AssociatedAccount(
            Type=AssociatedAccountNumberType.FEDEX_EXPRESS.value,
            AccountNumber=settings.account_number,
        ),
        TrackingNumber=None,
        OriginDetail=PickupOriginDetail(
            UseAccountAddress=None,
            PickupLocation=ContactAndAddress(
                Contact=Contact(
                    ContactId=None,
                    PersonName=payload.address.person_name,
                    CompanyName=payload.address.company_name,
                    PhoneNumber=payload.address.phone_number,
                    EMailAddress=payload.address.email,
                ),
                Address=Address(
                    StreetLines=SF.concat_str(payload.address.address_line1,
                                              payload.address.address_line2),
                    City=payload.address.city,
                    StateOrProvinceCode=payload.address.state_code,
                    PostalCode=payload.address.postal_code,
                    CountryCode=payload.address.country_code,
                    Residential=payload.address.residential,
                ),
            ),
            PackageLocation=payload.package_location,
            ReadyTimestamp=f"{payload.pickup_date}T{payload.ready_time}:00",
            CompanyCloseTime=f"{payload.closing_time}:00",
            PickupDateType=(PickupRequestType.SAME_DAY if same_day else
                            PickupRequestType.FUTURE_DAY).value,
            LastAccessTime=None,
            GeographicalPostalCode=None,
            Location=payload.package_location,
            DeleteLastUsed=None,
            SuppliesRequested=None,
            EarlyPickup=None,
        ),
        PickupServiceCategory=None,
        FreightPickupDetail=None,
        ExpressFreightDetail=None,
        PackageCount=len(packages) or 1,
        TotalWeight=Weight(Units=WeightUnits.LB.name, Value=packages.weight.LB)
        if len(packages) > 0 else None,
        CarrierCode=CarrierCodeType.FDXE.value,
        OversizePackageCount=None,
        Remarks=payload.instruction,
        CommodityDescription=None,
        CountryRelationship=None,
    )

    return Serializable(request, _request_serializer)
Example #4
0
def shipment_request(
    payload: ShipmentRequest, settings: Settings
) -> Serializable[ProcessShipmentRequest]:
    shipper = CompleteAddress.map(payload.shipper)
    recipient = CompleteAddress.map(payload.recipient)
    packages = Packages(payload.parcels, PackagePresets, required=["weight"])
    # Only the master package is selected here because even for MPS only one package is accepted for a master tracking.
    master_package = packages[0]

    service = ServiceType.map(payload.service).value_or_key
    options = Options(payload.options, SpecialServiceType)
    special_services = [getattr(v, 'value', v) for k, v in options if k in SpecialServiceType]
    label_type, label_format = LabelType[payload.label_type or 'PDF_4x6'].value
    customs = payload.customs
    duty = customs.duty if customs is not None else None
    bill_to = CompleteAddress(getattr(duty, 'bill_to', None))

    request = ProcessShipmentRequest(
        WebAuthenticationDetail=settings.webAuthenticationDetail,
        ClientDetail=settings.clientDetail,
        TransactionDetail=TransactionDetail(CustomerTransactionId="IE_v26_Ship"),
        Version=VersionId(ServiceId="ship", Major=26, Intermediate=0, Minor=0),
        RequestedShipment=RequestedShipment(
            ShipTimestamp=DF.date(options.shipment_date or datetime.now()),
            DropoffType="REGULAR_PICKUP",
            ServiceType=service,
            PackagingType=PackagingType[packages.package_type or 'your_packaging'].value,
            ManifestDetail=None,
            VariationOptions=None,
            TotalWeight=FedexWeight(
                Units=packages.weight.unit,
                Value=packages.weight.value
            ),
            TotalInsuredValue=options.insurance,
            PreferredCurrency=options.currency,
            ShipmentAuthorizationDetail=None,
            Shipper=Party(
                AccountNumber=settings.account_number,
                Tins=(
                    [TaxpayerIdentification(Number=tax) for tax in shipper.taxes]
                    if shipper.has_tax_info else None
                ),
                Contact=(
                    Contact(
                        ContactId=None,
                        PersonName=shipper.person_name,
                        Title=None,
                        CompanyName=shipper.company_name,
                        PhoneNumber=shipper.phone_number,
                        PhoneExtension=None,
                        TollFreePhoneNumber=None,
                        PagerNumber=None,
                        FaxNumber=None,
                        EMailAddress=shipper.email,
                    )
                    if shipper.has_contact_info else None
                ),
                Address=Address(
                    StreetLines=shipper.address_lines,
                    City=shipper.city,
                    StateOrProvinceCode=shipper.state_code,
                    PostalCode=shipper.postal_code,
                    UrbanizationCode=None,
                    CountryCode=shipper.country_code,
                    CountryName=shipper.country_name,
                    Residential=shipper.residential,
                    GeographicCoordinates=None,
                ),
            ),
            Recipient=Party(
                AccountNumber=None,
                Tins=(
                    [TaxpayerIdentification(Number=tax) for tax in recipient.taxes]
                    if recipient.has_tax_info else None
                ),
                Contact=(
                    Contact(
                        ContactId=None,
                        PersonName=recipient.person_name,
                        Title=None,
                        CompanyName=recipient.company_name,
                        PhoneNumber=recipient.phone_number,
                        PhoneExtension=None,
                        TollFreePhoneNumber=None,
                        PagerNumber=None,
                        FaxNumber=None,
                        EMailAddress=recipient.email,
                    )
                    if recipient.has_contact_info else None
                ),
                Address=Address(
                    StreetLines=recipient.address_lines,
                    City=recipient.city,
                    StateOrProvinceCode=recipient.state_code,
                    PostalCode=recipient.postal_code,
                    UrbanizationCode=None,
                    CountryCode=recipient.country_code,
                    CountryName=recipient.country_name,
                    Residential=recipient.residential,
                    GeographicCoordinates=None,
                ),
            ),
            RecipientLocationNumber=None,
            Origin=None,
            SoldTo=None,
            ShippingChargesPayment=Payment(
                PaymentType=PaymentType[payload.payment.paid_by or "sender"].value,
                Payor=Payor(
                    ResponsibleParty=Party(
                        AccountNumber=(payload.payment.account_number or settings.account_number),
                    )
                ),
            ),
            SpecialServicesRequested=(
                ShipmentSpecialServicesRequested(
                    SpecialServiceTypes=special_services,
                    CodDetail=(
                        CodDetail(
                            CodCollectionAmount=Money(
                                Currency=options.currency or "USD",
                                Amount=options.cash_on_delivery,
                            ),
                            AddTransportationChargesDetail=None,
                            CollectionType=CodCollectionType.CASH,
                            CodRecipient=None,
                            FinancialInstitutionContactAndAddress=None,
                            RemitToName=None,
                            ReferenceIndicator=None,
                            ReturnTrackingId=None,
                        )
                        if options.cash_on_delivery else None
                    ),
                    DeliveryOnInvoiceAcceptanceDetail=None,
                    HoldAtLocationDetail=None,
                    EventNotificationDetail=(
                        ShipmentEventNotificationDetail(
                            AggregationType=None,
                            PersonalMessage=None,
                            EventNotifications=[
                                ShipmentEventNotificationSpecification(
                                    Role=None,
                                    Events=NOTIFICATION_EVENTS,
                                    NotificationDetail=NotificationDetail(
                                        NotificationType="EMAIL",
                                        EmailDetail=EMailDetail(
                                            EmailAddress=(options.email_notification_to or recipient.email),
                                            Name=recipient.person_name or recipient.company_name,
                                        ),
                                        Localization=Localization(LanguageCode="EN"),
                                    ),
                                    FormatSpecification=ShipmentNotificationFormatSpecification(
                                        Type="TEXT"
                                    ),
                                )
                            ],
                        )
                        if options.email_notification and any([options.email_notification_to, recipient.email])
                        else None
                    ),
                    ReturnShipmentDetail=None,
                    PendingShipmentDetail=None,
                    InternationalControlledExportDetail=None,
                    InternationalTrafficInArmsRegulationsDetail=None,
                    ShipmentDryIceDetail=None,
                    HomeDeliveryPremiumDetail=None,
                    EtdDetail=None,
                )
                if options.has_content else None
            ),
            ExpressFreightDetail=None,
            FreightShipmentDetail=None,
            DeliveryInstructions=None,
            VariableHandlingChargeDetail=None,
            CustomsClearanceDetail=(
                CustomsClearanceDetail(
                    Brokers=None,
                    ClearanceBrokerage=None,
                    CustomsOptions=None,
                    ImporterOfRecord=None,
                    RecipientCustomsId=None,
                    DutiesPayment=(
                        Payment(
                            PaymentType=PaymentType[duty.paid_by or "sender"].value,
                            Payor=(
                                Payor(
                                    ResponsibleParty=Party(
                                        AccountNumber=duty.account_number,
                                        Tins=bill_to.taxes
                                    )
                                ) if any([duty.account_number, bill_to.taxes]) else None
                            )
                        ) if duty is not None else None
                    ),
                    DocumentContent=None,
                    CustomsValue=Money(
                        Currency=(duty.currency or options.currency),
                        Amount=(duty.declared_value or options.declared_value)
                    ),
                    FreightOnValue=None,
                    InsuranceCharges=None,
                    PartiesToTransactionAreRelated=None,
                    CommercialInvoice=(
                        CommercialInvoice(
                            Comments=None,
                            FreightCharge=None,
                            TaxesOrMiscellaneousChargeType=None,
                            PackingCosts=None,
                            HandlingCosts=None,
                            SpecialInstructions=None,
                            DeclarationStatement=None,
                            PaymentTerms=None,
                            Purpose=PurposeType[customs.content_type or 'other'].value,
                            PurposeOfShipmentDescription=None,
                            CustomerReferences=None,
                            OriginatorName=(shipper.company_name or shipper.person_name),
                            TermsOfSale=Incoterm[customs.incoterm or "DDU"].value
                        )
                        if customs.commercial_invoice else None
                    ),
                    Commodities=[
                        Commodity(
                            Name=None,
                            NumberOfPieces=item.quantity,
                            Description=item.description or "N/A",
                            Purpose=None,
                            CountryOfManufacture=item.origin_country,
                            HarmonizedCode=None,
                            Weight=FedexWeight(
                                Units=master_package.weight_unit.value,
                                Value=Weight(item.weight, item.weight_unit)[master_package.weight_unit.value]
                            ),
                            Quantity=item.quantity,
                            QuantityUnits='EA',
                            AdditionalMeasures=None,
                            UnitPrice=Money(
                                Currency=(options.currency or duty.currency),
                                Amount=item.value_amount,
                            ),
                            CustomsValue=None,
                            ExciseConditions=None,
                            ExportLicenseNumber=None,
                            ExportLicenseExpirationDate=None,
                            CIMarksAndNumbers=None,
                            PartNumber=item.sku,
                            NaftaDetail=None,
                        ) for item in customs.commodities
                    ],
                    ExportDetail=None,
                    RegulatoryControls=None,
                    DeclarationStatementDetail=None
                ) if payload.customs is not None else None
            ),
            PickupDetail=None,
            SmartPostDetail=None,
            BlockInsightVisibility=None,
            LabelSpecification=LabelSpecification(
                Dispositions=None,
                LabelFormatType=LabelFormatType.COMMON_2_D.value,
                ImageType=label_type,
                LabelStockType=label_format,
                LabelPrintingOrientation=LabelPrintingOrientationType.TOP_EDGE_OF_TEXT_FIRST.value,
                LabelOrder=LabelOrderType.SHIPPING_LABEL_FIRST.value,
                PrintedLabelOrigin=None,
                CustomerSpecifiedDetail=None,
            ),
            ShippingDocumentSpecification=None,
            RateRequestTypes=None,
            EdtRequestType=None,
            MasterTrackingId=None,
            PackageCount=len(packages),
            ConfigurationData=None,
            RequestedPackageLineItems=[
                RequestedPackageLineItem(
                    SequenceNumber=1,
                    GroupNumber=None,
                    GroupPackageCount=None,
                    VariableHandlingChargeDetail=None,
                    InsuredValue=None,
                    Weight=(
                        FedexWeight(
                            Units=master_package.weight.unit,
                            Value=master_package.weight.value,
                        )
                        if master_package.weight.value else None
                    ),
                    Dimensions=(
                        FedexDimensions(
                            Length=master_package.length.map(MeasurementOptions).value,
                            Width=master_package.width.map(MeasurementOptions).value,
                            Height=master_package.height.map(MeasurementOptions).value,
                            Units=master_package.dimension_unit.value,
                        )
                        if master_package.has_dimensions else None
                    ),
                    PhysicalPackaging=None,
                    ItemDescription=master_package.parcel.description,
                    ItemDescriptionForClearance=None,
                    CustomerReferences=(
                        [
                            CustomerReference(
                                CustomerReferenceType=CustomerReferenceType.CUSTOMER_REFERENCE,
                                Value=payload.reference
                            )
                        ]
                        if any(payload.reference or "") else None
                    ),
                    SpecialServicesRequested=None,
                    ContentRecords=None,
                )
            ],
        ),
    )
    return Serializable(request, _request_serializer)