Esempio n. 1
0
def _extract_rate(node: Element, settings: Settings) -> RateDetails:
    quote = XP.build(QuoteType, node)
    rate_provider, service, service_name = Service.info(
        quote.serviceId, quote.carrierId, quote.serviceName, quote.carrierName
    )
    surcharges = [
        ChargeDetails(
            name=charge.name, amount=NF.decimal(charge.amount), currency=quote.currency
        )
        for charge in cast(List[SurchargeType], quote.Surcharge)
    ]
    fuel_surcharge = (
        ChargeDetails(
            name="Fuel surcharge",
            amount=NF.decimal(quote.fuelSurcharge),
            currency=quote.currency,
        )
        if quote.fuelSurcharge is not None else None
    )

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        currency=quote.currency,
        service=service,
        base_charge=NF.decimal(quote.baseCharge),
        total_charge=NF.decimal(quote.totalCharge),
        transit_days=quote.transitDays,
        extra_charges=([fuel_surcharge] + surcharges),
        meta=dict(
            rate_provider=rate_provider,
            service_name=service_name
        )
    )
Esempio n. 2
0
def _extract_quote(node: Element, settings: Settings) -> RateDetails:
    quote = XP.to_object(price_quoteType, node)
    service = ServiceType.map(quote.service_code)
    adjustments = getattr(quote.price_details.adjustments, 'adjustment', [])
    discount = sum(NF.decimal(d.adjustment_cost or 0) for d in adjustments)
    transit_days = quote.service_standard.expected_transit_time

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        currency=Currency.CAD.name,
        transit_days=transit_days,
        service=service.name_or_key,
        base_charge=NF.decimal(quote.price_details.base or 0),
        total_charge=NF.decimal(quote.price_details.due or 0),
        discount=NF.decimal(discount),
        duties_and_taxes=NF.decimal(
            float(quote.price_details.taxes.gst.valueOf_ or 0)
            + float(quote.price_details.taxes.pst.valueOf_ or 0)
            + float(quote.price_details.taxes.hst.valueOf_ or 0)
        ),
        extra_charges=[
            ChargeDetails(
                name=a.adjustment_name,
                currency=Currency.CAD.name,
                amount=NF.decimal(a.adjustment_cost or 0),
            )
            for a in adjustments
        ],
        meta=dict(
            service_name=(service.name or quote.service_name)
        )
    )
Esempio n. 3
0
def _extract_details(service_node: Element, settings: Settings) -> RateDetails:
    service: ServiceType = ServiceType()
    service.build(service_node)
    currency = "USD"
    special_services: List[ExtraServiceType] = [
        XP.build(ExtraServiceType, svc)
        for svc in service_node.xpath(".//*[local-name() = $name]",
                                      name="ExtraService")
    ]
    delivery_date = DF.date(service.GuaranteeAvailability, "%m/%d/%Y")
    transit = ((delivery_date -
                datetime.now()).days if delivery_date is not None else None)
    rate_service: Service = Service.find(service.SvcDescription)

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=rate_service.value,
        base_charge=NF.decimal(service.Postage),
        total_charge=NF.decimal(service.Postage),
        currency=currency,
        transit_days=transit,
        extra_charges=[
            ChargeDetails(
                name=ExtraService(special.ServiceID).name,
                amount=NF.decimal(special.Price),
                currency=currency,
            ) for special in special_services
        ],
    )
Esempio n. 4
0
def _extract_details(postage_node: Element, settings: Settings) -> RateDetails:
    postage: PostageType = PostageType()
    postage.build(postage_node)
    currency = Currency.USD.name
    services: List[SpecialServiceType] = [
        XP.build(SpecialServiceType, svc)
        for svc in postage_node.xpath(".//*[local-name() = $name]",
                                      name="SpecialService")
    ]
    estimated_date = DF.date(postage.CommitmentDate)
    transit = ((estimated_date -
                datetime.now()).days if estimated_date is not None else None)
    postage_rate = postage_node.find("Rate").text

    def get(key: str) -> Any:
        return reduce(lambda r, v: v.text, postage_node.findall(key), None)

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=Service.find(get("MailService")).name,
        total_charge=NF.decimal(postage_rate),
        currency=currency,
        transit_days=transit,
        extra_charges=[
            ChargeDetails(
                name=SpecialService(str(svc.ServiceID)).name,
                amount=NF.decimal(svc.Price),
                currency=currency,
            ) for svc in services
        ],
    )
Esempio n. 5
0
def _extract_rate_details(node: Element, settings: Settings) -> RateDetails:
    shipment = XP.build(Shipment, node)
    surcharges = [
        ChargeDetails(name=charge.value,
                      amount=NF.decimal(getattr(shipment, charge.name)),
                      currency='CAD') for charge in list(Charges)
        if NF.decimal(getattr(shipment, charge.name)) > 0.0
    ]
    taxes = [
        ChargeDetails(name=f'{getattr(shipment, code)} Tax Charge',
                      amount=NF.decimal(charge),
                      currency='CAD')
        for code, charge in [(
            'tax_code_1',
            shipment.tax_charge_1), ('tax_code_2', shipment.tax_charge_2)]
        if NF.decimal(charge) > 0.0
    ]

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        currency="CAD",
        transit_days=shipment.transit_time,
        service=Service(shipment.service_type).name,
        base_charge=NF.decimal(shipment.freight_charge),
        total_charge=sum([c.amount for c in (surcharges + taxes)], 0.0),
        duties_and_taxes=sum([t.amount for t in taxes], 0.0),
        extra_charges=(surcharges + taxes),
    )
Esempio n. 6
0
def _extract_intl_rates(service_node: Element,
                        settings: Settings) -> RateDetails:
    service: ServiceType = ServiceType()
    service.build(service_node)
    currency = "USD"
    special_services: List[ExtraServiceType] = [
        (lambda s: (s, s.build(svc)))(ExtraServiceType())[0]
        for svc in service_node.xpath(".//*[local-name() = $name]",
                                      name="ExtraService")
    ]
    delivery_date = (format_date(service.GuaranteeAvailability, "%m/%d/%Y")
                     if service.GuaranteeAvailability is not None else None)

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=service.SvcDescription,
        base_charge=decimal(service.Postage),
        total_charge=decimal(service.Postage),
        currency=currency,
        estimated_delivery=delivery_date,
        extra_charges=[
            ChargeDetails(
                name=ExtraService(special.ServiceID).name,
                amount=decimal(special.Price),
                currency=currency,
            ) for special in special_services
        ],
    )
Esempio n. 7
0
def _extract_details(postage_node: Element, settings: Settings) -> RateDetails:
    postage: PostageType = XP.build(PostageType, postage_node)
    charges: List[SpecialServiceType] = postage.SpecialServices.SpecialService
    estimated_date = DF.date(postage.CommitmentDate)
    transit = (
        (estimated_date - datetime.now()).days
        if estimated_date is not None else None
    )

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=ServiceClassID(str(postage.CLASSID)),
        total_charge=NF.decimal(postage.Rate),
        currency=Currency.USD.name,
        transit_days=transit,
        extra_charges=[
            ChargeDetails(
                name=charge.ServiceName,
                amount=NF.decimal(charge.Price),
                currency=Currency.USD.name,
            )
            for charge in charges
        ]
    )
Esempio n. 8
0
def _extract_details(postage_node: Element, settings: Settings) -> RateDetails:
    postage: ServiceType = XP.to_object(ServiceType, postage_node)

    service = ServiceClassID.map(str(postage.ID))
    charges: List[ExtraServiceType] = postage.ExtraServices.ExtraService
    delivery_date = DF.date(postage.GuaranteeAvailability, "%m/%d/%Y")
    transit = ((delivery_date.date() - datetime.now().date()).days if delivery_date is not None else None)

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,

        service=service.name_or_key,
        base_charge=NF.decimal(postage.Postage),
        total_charge=NF.decimal(postage.Postage),
        currency=Currency.USD.name,
        transit_days=transit,
        extra_charges=[
            ChargeDetails(
                name=charge.ServiceName,
                amount=NF.decimal(charge.Price),
                currency=Currency.USD.name,
            )
            for charge in charges
        ],
        meta=dict(service_name=service.name or postage.SvcDescription)
    )
Esempio n. 9
0
def _extract_details(response: Element, settings: Settings) -> ShipmentDetails:
    shipment = XP.build(eVSResponse, response)
    charges: List[ExtraServiceType] = shipment.ExtraServices.ExtraService
    total_charge = sum([
        NF.decimal(shipment.Postage), *[NF.decimal(c.Price) for c in charges]
    ], 0.0)

    return ShipmentDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           label=shipment.LabelImage,
                           tracking_number=shipment.BarcodeNumber,
                           shipment_identifier=shipment.BarcodeNumber,
                           selected_rate=RateDetails(
                               carrier_name=settings.carrier_name,
                               carrier_id=settings.carrier_id,
                               service=ServiceClassID(shipment).name,
                               currency=Currency.USD.value,
                               base_charge=NF.decimal(shipment.Postage),
                               total_charge=total_charge,
                               extra_charges=[
                                   ChargeDetails(name=charge.ServiceName,
                                                 amount=NF.decimal(
                                                     charge.Price),
                                                 currency=Currency.USD.value)
                                   for charge in charges
                               ]))
Esempio n. 10
0
def _extract_rate_details(response: Tuple[Element, ResponseGetCharges],
                          settings: Settings) -> RateDetails:
    product, rate = response
    charges = [
        *[(charge.SurChargeName, charge.SurChargeAmount)
          for charge in cast(List[SurCharge], rate.SurCharges)],
        *[(name, value)
          for name, value in [("Fuel Charges", rate.FuelCharges),
                              ("Insurance Charges", rate.InsuranceCharges)]
          if (value or 0) > 0]
    ]

    return RateDetails(carrier_name=settings.carrier_name,
                       carrier_id=settings.carrier_id,
                       service=Service(product.text),
                       currency=Currency.CAD.name,
                       base_charge=NF.decimal(rate.BaseCharges),
                       total_charge=NF.decimal(rate.BaseCharges),
                       extra_charges=[
                           ChargeDetails(
                               name=name,
                               amount=amount,
                               currency=Currency.CAD.name,
                           ) for name, amount in charges
                       ])
Esempio n. 11
0
def _extract_details(service_node: Element, settings: Settings) -> RateDetails:
    service: ServiceType = XP.build(ServiceType, service_node)
    charges: List[ExtraServiceType] = service.ExtraServices.ExtraService
    delivery_date = DF.date(service.GuaranteeAvailability, "%m/%d/%Y")
    transit = (
        (delivery_date - datetime.now()).days
        if delivery_date is not None else None
    )

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,

        service=ServiceClassID(str(service.ID)),
        base_charge=NF.decimal(service.Postage),
        total_charge=NF.decimal(service.Postage),
        currency=Currency.USD.name,
        transit_days=transit,
        extra_charges=[
            ChargeDetails(
                name=charge.ServiceID,
                amount=NF.decimal(charge.Price),
                currency=Currency.USD.name,
            )
            for charge in charges
        ],
    )
Esempio n. 12
0
def _extract_details(postage_node: Element, settings: Settings) -> RateDetails:
    postage: PostageType = XP.to_object(PostageType, postage_node)

    service = ServiceClassID.map(str(postage.CLASSID))
    charges: List[SpecialServiceType] = getattr(postage.SpecialServices,
                                                'SpecialService', [])
    rate = NF.decimal(XP.find('Rate', postage_node, first=True).text)
    estimated_date = DF.date(
        getattr(XP.find('CommitmentDate', postage_node, first=True), 'text',
                None))
    transit = ((estimated_date.date() - datetime.now().date()).days
               if estimated_date is not None else None)

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=service.name_or_key,
        base_charge=rate,
        total_charge=rate,
        currency=Currency.USD.name,
        transit_days=transit,
        extra_charges=[
            ChargeDetails(
                name=charge.ServiceName,
                amount=NF.decimal(charge.Price),
                currency=Currency.USD.name,
            ) for charge in charges
        ],
        meta=dict(service_name=(service.name or postage.MailService)))
Esempio n. 13
0
    def extract(rates: List[RateDetails],
                detail_node: Element) -> List[RateDetails]:
        rate = XP.build(RatedShipmentType, detail_node)

        if rate.NegotiatedRateCharges is not None:
            total_charges = (rate.NegotiatedRateCharges.TotalChargesWithTaxes
                             or rate.NegotiatedRateCharges.TotalCharge)
            taxes = rate.NegotiatedRateCharges.TaxCharges
            itemized_charges = rate.NegotiatedRateCharges.ItemizedCharges + taxes
        else:
            total_charges = rate.TotalChargesWithTaxes or rate.TotalCharges
            taxes = rate.TaxCharges
            itemized_charges = rate.ItemizedCharges + taxes

        extra_charges = itemized_charges + [rate.ServiceOptionsCharges]
        estimated_arrival = next(
            (XP.build(EstimatedArrivalType, n)
             for n in detail_node.xpath(".//*[local-name() = $name]",
                                        name="EstimatedArrival")),
            EstimatedArrivalType(),
        )
        transit_days = (rate.GuaranteedDelivery.BusinessDaysInTransit
                        if rate.GuaranteedDelivery is not None else
                        estimated_arrival.BusinessDaysInTransit)
        currency_ = next(
            str(c.text)
            for c in detail_node.xpath(".//*[local-name() = $name]",
                                       name="CurrencyCode"))
        service = ShippingServiceCode(rate.Service.Code).name
        return rates + [
            RateDetails(
                carrier_name=settings.carrier_name,
                carrier_id=settings.carrier_id,
                currency=currency_,
                service=service,
                base_charge=NF.decimal(
                    rate.TransportationCharges.MonetaryValue),
                total_charge=NF.decimal(total_charges.MonetaryValue),
                duties_and_taxes=reduce(
                    lambda total, charge: total + NF.decimal(charge.
                                                             MonetaryValue),
                    taxes or [],
                    0.0,
                ),
                extra_charges=reduce(
                    lambda total, charge: (total + [
                        ChargeDetails(
                            name=charge.Code,
                            amount=NF.decimal(charge.MonetaryValue),
                            currency=charge.CurrencyCode,
                        )
                    ]),
                    [charge for charge in extra_charges if charge is not None],
                    [],
                ),
                transit_days=NF.integer(transit_days),
            )
        ]
Esempio n. 14
0
    def extract(rates: List[RateDetails],
                detail_node: Element) -> List[RateDetails]:
        rate = XP.to_object(RatedShipmentType, detail_node)

        if rate.NegotiatedRateCharges is not None:
            total_charges = (rate.NegotiatedRateCharges.TotalChargesWithTaxes
                             or rate.NegotiatedRateCharges.TotalCharge)
            taxes = rate.NegotiatedRateCharges.TaxCharges
            itemized_charges = rate.NegotiatedRateCharges.ItemizedCharges + taxes
        else:
            total_charges = rate.TotalChargesWithTaxes or rate.TotalCharges
            taxes = rate.TaxCharges
            itemized_charges = rate.ItemizedCharges + taxes

        extra_charges = itemized_charges + [rate.ServiceOptionsCharges]
        estimated_arrival = (XP.find(
            "EstimatedArrival", detail_node, EstimatedArrivalType, first=True)
                             or EstimatedArrivalType())
        transit_days = (rate.GuaranteedDelivery.BusinessDaysInTransit
                        if rate.GuaranteedDelivery is not None else
                        estimated_arrival.BusinessDaysInTransit)
        currency = XP.find("CurrencyCode", detail_node, first=True).text
        service = ServiceCode.map(rate.Service.Code)

        return rates + [
            RateDetails(
                carrier_name=settings.carrier_name,
                carrier_id=settings.carrier_id,
                currency=currency,
                service=service.name_or_key,
                base_charge=NF.decimal(
                    rate.TransportationCharges.MonetaryValue),
                total_charge=NF.decimal(total_charges.MonetaryValue),
                duties_and_taxes=reduce(
                    lambda total, charge: total + NF.decimal(charge.
                                                             MonetaryValue),
                    taxes or [],
                    0.0,
                ),
                extra_charges=reduce(
                    lambda total, charge: (total + [
                        ChargeDetails(
                            name=charge.Code,
                            amount=NF.decimal(charge.MonetaryValue),
                            currency=charge.CurrencyCode,
                        )
                    ]),
                    [
                        charge for charge in extra_charges
                        if charge is not None and charge.Code is not None
                    ],
                    [],
                ),
                transit_days=NF.integer(transit_days),
                meta=dict(service_name=service.name_or_key))
        ]
Esempio n. 15
0
def _extract_shipment(node: Element, settings: Settings) -> ShipmentDetails:
    shipping = XP.build(ShippingReplyType, node)
    quote: QuoteType = shipping.Quote

    tracking_number = getattr(next(iter(shipping.Package), None), 'trackingNumber', None)
    rate_provider, service, service_name = Service.info(
        quote.serviceId, quote.carrierId, quote.serviceName, quote.carrierName
    )
    surcharges = [
        ChargeDetails(
            name=charge.name,
            currency=quote.currency,
            amount=NF.decimal(charge.amount),
        )
        for charge in cast(List[SurchargeType], quote.Surcharge)
    ]
    fuel_surcharge = (
        ChargeDetails(
            name="Fuel surcharge",
            currency=quote.currency,
            amount=NF.decimal(quote.fuelSurcharge),
        )
        if quote.fuelSurcharge is not None else None
    )

    return ShipmentDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=tracking_number,
        shipment_identifier=shipping.Order.id,
        label=shipping.Labels,
        selected_rate=(
            RateDetails(
                carrier_name=settings.carrier_name,
                carrier_id=settings.carrier_id,
                service=service,
                currency=quote.currency,
                base_charge=NF.decimal(quote.baseCharge),
                total_charge=NF.decimal(quote.totalCharge),
                transit_days=quote.transitDays,
                extra_charges=([fuel_surcharge] + surcharges),
                meta=dict(
                    rate_provider=rate_provider,
                    service_name=service_name
                )
            ) if quote is not None else None
        ),
        meta=dict(
            rate_provider=rate_provider,
            service_name=service_name,
            tracking_url=shipping.TrackingURL
        )
    )
Esempio n. 16
0
def _extract_rate(detail_node: Element, settings: Settings) -> Optional[RateDetails]:
    rate: RateReplyDetail = XP.to_object(RateReplyDetail, detail_node)
    service = ServiceType.map(rate.ServiceType)
    rate_type = rate.ActualRateType
    shipment_rate, shipment_discount = cast(
        Tuple[ShipmentRateDetail, Money],
        next(
            (
                (r.ShipmentRateDetail, r.EffectiveNetDiscount)
                for r in rate.RatedShipmentDetails
                if cast(ShipmentRateDetail, r.ShipmentRateDetail).RateType == rate_type
            ),
            (None, None),
        ),
    )
    discount = (
        NF.decimal(shipment_discount.Amount) if shipment_discount is not None else None
    )
    currency = cast(Money, shipment_rate.TotalBaseCharge).Currency
    duties_and_taxes = (
        shipment_rate.TotalTaxes.Amount + shipment_rate.TotalDutiesAndTaxes.Amount
    )
    surcharges = [
        ChargeDetails(
            name=cast(Surcharge, s).Description,
            amount=NF.decimal(cast(Surcharge, s).Amount.Amount),
            currency=currency,
        )
        for s in shipment_rate.Surcharges + shipment_rate.Taxes
    ]
    estimated_delivery = DF.date(rate.DeliveryTimestamp)
    transit = (
        ((estimated_delivery.date() - datetime.today().date()).days or None)
        if estimated_delivery is not None else None
    )

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=service.name_or_key,
        currency=currency,
        base_charge=NF.decimal(shipment_rate.TotalBaseCharge.Amount),
        total_charge=NF.decimal(shipment_rate.TotalNetChargeWithDutiesAndTaxes.Amount),
        duties_and_taxes=NF.decimal(duties_and_taxes),
        discount=discount,
        transit_days=transit,
        extra_charges=surcharges,
        meta=dict(service_name=service.name_or_key)
    )
Esempio n. 17
0
def _extract_quote(qtdshp_node: Element, settings: Settings) -> RateDetails:
    qtdshp = ResponseQtdShpType()
    qtdshp.build(qtdshp_node)
    if qtdshp.ShippingCharge is None or qtdshp.ShippingCharge == 0:
        return None

    ExtraCharges = list(
        map(
            lambda s: ChargeDetails(name=s.LocalServiceTypeName,
                                    amount=NF.decimal(s.ChargeValue or 0)),
            qtdshp.QtdShpExChrg,
        ))
    Discount_ = reduce(
        lambda d, ec: d + ec.amount
        if "Discount" in ec.name else d, ExtraCharges, 0.0)
    DutiesAndTaxes_ = reduce(
        lambda d, ec: d + ec.amount
        if "TAXES PAID" in ec.name else d, ExtraCharges, 0.0)
    delivery_date = DF.date(qtdshp.DeliveryDate[0].DlvyDateTime,
                            "%Y-%m-%d %H:%M:%S")
    pricing_date = DF.date(qtdshp.PricingDate)
    transit = ((delivery_date - pricing_date).days
               if all([delivery_date, pricing_date]) else None)
    service_name = next(
        (p.name for p in ProductCode if p.value == qtdshp.GlobalProductCode),
        None,
    )
    return RateDetails(carrier_name=settings.carrier_name,
                       carrier_id=settings.carrier_id,
                       currency=qtdshp.CurrencyCode,
                       transit_days=transit,
                       service=(service_name or qtdshp.GlobalProductCode),
                       base_charge=NF.decimal(qtdshp.WeightCharge),
                       total_charge=NF.decimal(qtdshp.ShippingCharge),
                       duties_and_taxes=NF.decimal(DutiesAndTaxes_),
                       discount=NF.decimal(Discount_),
                       extra_charges=list(
                           map(
                               lambda s: ChargeDetails(
                                   name=s.LocalServiceTypeName,
                                   amount=NF.decimal(s.ChargeValue),
                                   currency=qtdshp.CurrencyCode,
                               ),
                               qtdshp.QtdShpExChrg,
                           )),
                       meta=(dict(service=qtdshp.GlobalProductCode,
                                  service_name=qtdshp.ProductShortName)
                             if service_name is None else None))
Esempio n. 18
0
def _extract_quote(qtdshp_node: Element, settings: Settings) -> RateDetails:
    qtdshp = ResponseQtdShpType()
    qtdshp.build(qtdshp_node)
    if qtdshp.ShippingCharge is None or qtdshp.ShippingCharge == 0:
        return None

    ExtraCharges = list(
        map(
            lambda s: ChargeDetails(name=s.LocalServiceTypeName,
                                    amount=decimal(s.ChargeValue or 0)),
            qtdshp.QtdShpExChrg,
        ))
    Discount_ = reduce(
        lambda d, ec: d + ec.amount
        if "Discount" in ec.name else d, ExtraCharges, 0.0)
    DutiesAndTaxes_ = reduce(
        lambda d, ec: d + ec.amount
        if "TAXES PAID" in ec.name else d, ExtraCharges, 0.0)
    DlvyDateTime = qtdshp.DeliveryDate[0].DlvyDateTime
    delivery_date = (datetime.strptime(
        str(DlvyDateTime), "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d")
                     if DlvyDateTime is not None else None)
    service_name = next(
        (p.name for p in Product if p.value in qtdshp.LocalProductName),
        qtdshp.LocalProductName,
    )
    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        currency=qtdshp.CurrencyCode,
        estimated_delivery=format_date(delivery_date),
        service=service_name,
        base_charge=decimal(qtdshp.WeightCharge),
        total_charge=decimal(qtdshp.ShippingCharge),
        duties_and_taxes=decimal(DutiesAndTaxes_),
        discount=decimal(Discount_),
        extra_charges=list(
            map(
                lambda s: ChargeDetails(name=s.LocalServiceTypeName,
                                        amount=decimal(s.ChargeValue),
                                        currency=qtdshp.CurrencyCode),
                qtdshp.QtdShpExChrg,
            )),
    )
Esempio n. 19
0
def _extract_detail(details: Tuple[ratedServices, ratedService],
                    settings: Settings) -> RateDetails:
    rate, service = details
    charges: List[chargeElement] = service.chargeElements.chargeElement

    return RateDetails(carrier_name=settings.carrier_name,
                       carrier_id=settings.carrier_id,
                       currency=rate.currency,
                       service=str(service.product.id),
                       base_charge=NF.decimal(service.totalPriceExclVat),
                       total_charge=NF.decimal(service.totalPrice),
                       duties_and_taxes=NF.decimal(service.vatAmount),
                       extra_charges=[
                           ChargeDetails(name=charge.description,
                                         amount=NF.decimal(charge.chargeValue),
                                         currency=rate.currency)
                           for charge in charges
                       ],
                       meta=dict(service_name=service.product.productDesc))
Esempio n. 20
0
def _extract_rate(estimate_node: Element, settings: Settings) -> RateDetails:
    estimate = ShipmentEstimate()
    estimate.build(estimate_node)
    currency = Currency.CAD.name
    duties_and_taxes = [
        ChargeDetails(
            name=cast(Tax, tax).Description,
            amount=decimal(cast(Tax, tax).Amount),
            currency=currency,
        )
        for tax in estimate.Taxes.Tax
    ]
    surcharges = [
        ChargeDetails(
            name=cast(Surcharge, charge).Description,
            amount=decimal(cast(Surcharge, charge).Amount),
            currency=currency,
        )
        for charge in estimate.Surcharges.Surcharge
    ]
    option_charges = [
        ChargeDetails(
            name=cast(OptionPrice, charge).Description,
            amount=decimal(cast(OptionPrice, charge).Amount),
            currency=currency,
        )
        for charge in estimate.OptionPrices.OptionPrice
    ]
    service = next(
        (p.name for p in Product if p.value in estimate.ServiceID), estimate.ServiceID
    )
    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=service,
        currency=currency,
        base_charge=decimal(estimate.BasePrice),
        transit_days=estimate.EstimatedTransitDays,
        total_charge=decimal(estimate.TotalPrice),
        duties_and_taxes=decimal(sum(c.amount for c in duties_and_taxes)),
        extra_charges=(duties_and_taxes + surcharges + option_charges),
    )
Esempio n. 21
0
def _extract_details(rate: Rate, response: RateResponse,
                     settings: Settings) -> RateDetails:

    return RateDetails(carrier_id=settings.carrier_id,
                       carrier_name=settings.carrier_name,
                       currency="CAD",
                       transit_days=response.delay,
                       service=Service(rate.rateType),
                       discount=NF.decimal(rate.discountAmount),
                       base_charge=NF.decimal(rate.basicCharge),
                       total_charge=NF.decimal(rate.total),
                       duties_and_taxes=NF.decimal(rate.taxes),
                       extra_charges=[
                           ChargeDetails(
                               name=charge.name,
                               amount=NF.decimal(charge.amount),
                               currency="CAD",
                           ) for charge in rate.surcharges
                       ],
                       meta=dict(accountType=rate.accountType))
Esempio n. 22
0
def _extract_rate(detail_node: Element,
                  settings: Settings) -> Optional[RateDetails]:
    rate: RateReplyDetail = RateReplyDetail()
    rate.build(detail_node)

    service = ServiceType(rate.ServiceType).name
    rate_type = rate.ActualRateType
    shipment_rate, shipment_discount = cast(
        Tuple[ShipmentRateDetail, Money],
        next(((r.ShipmentRateDetail, r.EffectiveNetDiscount)
              for r in rate.RatedShipmentDetails
              if cast(ShipmentRateDetail, r.ShipmentRateDetail).RateType ==
              rate_type), (None, None)))
    discount = decimal(
        shipment_discount.Amount) if shipment_discount is not None else None
    currency = cast(Money, shipment_rate.TotalBaseCharge).Currency
    duties_and_taxes = shipment_rate.TotalTaxes.Amount + shipment_rate.TotalDutiesAndTaxes.Amount
    surcharges = [
        ChargeDetails(name=cast(Surcharge, s).Description,
                      amount=decimal(cast(Surcharge, s).Amount.Amount),
                      currency=currency)
        for s in shipment_rate.Surcharges + shipment_rate.Taxes
    ]
    estimated_delivery = to_date(rate.DeliveryTimestamp, "%Y-%m-%d %H:%M:%S")
    transit = ((estimated_delivery - datetime.now()).days
               if estimated_delivery is not None else None)

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=service,
        currency=currency,
        base_charge=decimal(shipment_rate.TotalBaseCharge.Amount),
        total_charge=decimal(
            shipment_rate.TotalNetChargeWithDutiesAndTaxes.Amount),
        duties_and_taxes=decimal(duties_and_taxes),
        discount=discount,
        transit_days=transit,
        extra_charges=surcharges,
    )
Esempio n. 23
0
def _extract_quote(price_quote_node: Element, settings: Settings) -> RateDetails:
    price_quote = price_quoteType()
    price_quote.build(price_quote_node)
    currency = Currency.CAD.name
    discounts = [
        ChargeDetails(
            name=d.adjustment_name,
            currency=currency,
            amount=decimal(d.adjustment_cost or 0),
        )
        for d in price_quote.price_details.adjustments.adjustment
    ]
    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        currency=currency,
        estimated_delivery=format_date(
            price_quote.service_standard.expected_delivery_date
        ),
        service=ServiceType(price_quote.service_code).name,
        base_charge=decimal(price_quote.price_details.base or 0),
        total_charge=decimal(price_quote.price_details.due or 0),
        discount=decimal(reduce(lambda total, d: total + d.amount, discounts, 0.0)),
        duties_and_taxes=decimal(
            float(price_quote.price_details.taxes.gst.valueOf_ or 0)
            + float(price_quote.price_details.taxes.pst.valueOf_ or 0)
            + float(price_quote.price_details.taxes.hst.valueOf_ or 0)
        ),
        extra_charges=list(
            map(
                lambda a: ChargeDetails(
                    name=a.adjustment_name,
                    currency=currency,
                    amount=decimal(a.adjustment_cost or 0),
                ),
                price_quote.price_details.adjustments.adjustment,
            )
        ),
    )
Esempio n. 24
0
def _extract_quote(quote: ResponseQtdShpType,
                   settings: Settings) -> RateDetails:
    service = ProductCode.map(quote.GlobalProductCode)
    ExtraCharges = [
        ChargeDetails(name=s.LocalServiceTypeName,
                      amount=NF.decimal(s.ChargeValue or 0))
        for s in quote.QtdShpExChrg
    ]
    discount = reduce(
        lambda d, ec: d + ec.amount
        if "Discount" in ec.name else d, ExtraCharges, 0.0)
    duties_and_taxes = reduce(
        lambda d, ec: d + ec.amount
        if "TAXES PAID" in ec.name else d, ExtraCharges, 0.0)
    delivery_date = DF.date(quote.DeliveryDate[0].DlvyDateTime,
                            "%Y-%m-%d %H:%M:%S")
    pricing_date = DF.date(quote.PricingDate)
    transit = ((delivery_date.date() - pricing_date.date()).days
               if all([delivery_date, pricing_date]) else None)

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        currency=quote.CurrencyCode,
        transit_days=transit,
        service=service.name_or_key,
        base_charge=NF.decimal(quote.WeightCharge),
        total_charge=NF.decimal(quote.ShippingCharge),
        duties_and_taxes=NF.decimal(duties_and_taxes),
        discount=NF.decimal(discount),
        extra_charges=[
            ChargeDetails(
                name=s.LocalServiceTypeName,
                amount=NF.decimal(s.ChargeValue),
                currency=quote.CurrencyCode,
            ) for s in quote.QtdShpExChrg
        ],
        meta=dict(service_name=(service.name or quote.ProductShortName)))
Esempio n. 25
0
def _extract_freight_rate(detail_node: Element,
                          settings: Settings) -> RateDetails:
    detail = FreightRateResponse()
    detail.build(detail_node)

    total_charge = [r for r in detail.Rate if r.Type.Code == "AFTR_DSCNT"][0]
    Discounts_ = [
        ChargeDetails(
            name=r.Type.Code,
            currency=r.Factor.UnitOfMeasurement.Code,
            amount=decimal(r.Factor.Value),
        ) for r in detail.Rate if r.Type.Code == "DSCNT"
    ]
    Surcharges_ = [
        ChargeDetails(
            name=r.Type.Code,
            currency=r.Factor.UnitOfMeasurement.Code,
            amount=decimal(r.Factor.Value),
        ) for r in detail.Rate if r.Type.Code not in
        ["DSCNT", "AFTR_DSCNT", "DSCNT_RATE", "LND_GROSS"]
    ]
    extra_charges = Discounts_ + Surcharges_
    currency_ = next(c.text
                     for c in detail_node.xpath(".//*[local-name() = $name]",
                                                name="CurrencyCode"))
    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        currency=currency_,
        service=detail.Service.Description,
        base_charge=decimal(detail.TotalShipmentCharge.MonetaryValue),
        total_charge=decimal(total_charge.Factor.Value or 0.0),
        duties_and_taxes=decimal(
            reduce(lambda r, c: r + c.amount, Surcharges_, 0.0)),
        discount=decimal(reduce(lambda r, c: r + c.amount, Discounts_, 0.0)),
        extra_charges=extra_charges,
    )
Esempio n. 26
0
def _extract_rate(estimate_node: Element, settings: Settings) -> RateDetails:
    estimate = XP.to_object(ShipmentEstimate, estimate_node)
    currency = Currency.CAD.name
    service = Product.map(estimate.ServiceID)
    duties_and_taxes = [
        ChargeDetails(
            name=cast(Tax, tax).Description,
            amount=NF.decimal(cast(Tax, tax).Amount),
            currency=currency,
        ) for tax in estimate.Taxes.Tax
    ]
    surcharges = [
        ChargeDetails(
            name=cast(Surcharge, charge).Description,
            amount=NF.decimal(cast(Surcharge, charge).Amount),
            currency=currency,
        ) for charge in estimate.Surcharges.Surcharge
    ]
    option_charges = [
        ChargeDetails(
            name=cast(OptionPrice, charge).Description,
            amount=NF.decimal(cast(OptionPrice, charge).Amount),
            currency=currency,
        ) for charge in estimate.OptionPrices.OptionPrice
    ]

    return RateDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        service=service.name_or_key,
        currency=currency,
        base_charge=NF.decimal(estimate.BasePrice),
        transit_days=estimate.EstimatedTransitDays,
        total_charge=NF.decimal(estimate.TotalPrice),
        duties_and_taxes=NF.decimal(sum(c.amount for c in duties_and_taxes)),
        extra_charges=(duties_and_taxes + surcharges + option_charges),
        meta=dict(service_name=service.name_or_key))
Esempio n. 27
0
    def extract(rates: List[RateDetails], detail_node: Element) -> List[RateDetails]:
        rate = RatedShipmentType()
        rate.build(detail_node)

        if rate.NegotiatedRateCharges is not None:
            total_charges = (
                rate.NegotiatedRateCharges.TotalChargesWithTaxes
                or rate.NegotiatedRateCharges.TotalCharge
            )
            taxes = rate.NegotiatedRateCharges.TaxCharges
            itemized_charges = rate.NegotiatedRateCharges.ItemizedCharges + taxes
        else:
            total_charges = rate.TotalChargesWithTaxes or rate.TotalCharges
            taxes = rate.TaxCharges
            itemized_charges = rate.ItemizedCharges + taxes

        extra_charges = itemized_charges + [rate.ServiceOptionsCharges]

        arrival = PickupType()
        [
            arrival.build(arrival)
            for arrival in detail_node.xpath(
                ".//*[local-name() = $name]", name="Arrival"
            )
        ]
        currency_ = next(
            c.text
            for c in detail_node.xpath(
                ".//*[local-name() = $name]", name="CurrencyCode"
            )
        )
        service = ShippingServiceCode(rate.Service.Code).name
        return rates + [
            RateDetails(
                carrier_name=settings.carrier_name,
                carrier_id=settings.carrier_id,
                currency=currency_,
                service=service,
                base_charge=decimal(rate.TransportationCharges.MonetaryValue),
                total_charge=decimal(total_charges.MonetaryValue),
                duties_and_taxes=reduce(
                    lambda total, charge: total + decimal(charge.MonetaryValue),
                    taxes or [],
                    0.0,
                ),
                extra_charges=reduce(
                    lambda total, charge: (
                        total
                        + [
                            ChargeDetails(
                                name=charge.Code,
                                amount=decimal(charge.MonetaryValue),
                                currency=charge.CurrencyCode,
                            )
                        ]
                    ),
                    [charge for charge in extra_charges if charge is not None],
                    [],
                ),
                estimated_delivery=format_date(arrival.Date),
            )
        ]
Esempio n. 28
0
    }],
    "services": [],
    "carrier_ids": ["canadapost"]
}

RETURNED_VALUE = (
    [
        RateDetails(carrier_id="canadapost",
                    carrier_name="canadapost",
                    currency="CAD",
                    transit_days=7,
                    service="canadapost_expedited_parcel",
                    discount=-0.95,
                    base_charge=29.64,
                    total_charge=32.99,
                    duties_and_taxes=4.3,
                    extra_charges=[
                        ChargeDetails(amount=1.24,
                                      currency="CAD",
                                      name="Fuel surcharge"),
                        ChargeDetails(amount=-2.19,
                                      currency="CAD",
                                      name="SMB Savings")
                    ]),
        RateDetails(carrier_id="canadapost",
                    carrier_name="canadapost",
                    currency="CAD",
                    transit_days=2,
                    service="canadapost_xpresspost",
                    discount=-1.34,
                    base_charge=75.82,
    "test_mode": True,
    "messages": [],
}

SHIPMENT_OPTIONS = {"insurance": 54, "currency": "CAD"}

RETURNED_RATES_VALUE = (
    [
        RateDetails(
            carrier_id="canadapost",
            carrier_name="canadapost",
            currency="CAD",
            transit_days=2,
            service="canadapost_priority",
            discount=-9.04,
            base_charge=101.83,
            total_charge=106.71,
            duties_and_taxes=13.92,
            extra_charges=[
                ChargeDetails(amount=2.7, currency="CAD", name="Fuel surcharge"),
                ChargeDetails(amount=-11.74, currency="CAD", name="SMB Savings"),
            ],
        )
    ],
    [],
)

SHIPMENT_PURCHASE_DATA = {"selected_rate_id": "rat_f5c1317021cb4b3c8a5d3b7369ed99e4"}

SELECTED_RATE = {
    "id": ANY,