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 ], )
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), )
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 ]))
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 ])
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 ], )
def _extract_pickup_details(response: Element, settings: Settings) -> PickupDetails: header = next((XP.build(PickupRequestHeaderType, elt) for elt in response.xpath(".//*[local-name() = $name]", name="pickup-request-header"))) price = next((XP.build(PickupRequestPriceType, elt) for elt in response.xpath(".//*[local-name() = $name]", name="pickup-request-price")), None) price_amount = sum( [ NF.decimal(price.hst_amount or 0.0), NF.decimal(price.gst_amount or 0.0), NF.decimal(price.due_amount or 0.0), ], 0.0, ) if price is not None else None return PickupDetails( carrier_id=settings.carrier_id, carrier_name=settings.carrier_name, confirmation_number=header.request_id, pickup_date=DF.fdate(header.next_pickup_date), pickup_charge=ChargeDetails(name="Pickup fees", amount=NF.decimal(price_amount), currency="CAD") if price is not None else None, )
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)))
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 ) )
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 ], )
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) )
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 ] )
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), ) ]
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)) ]
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 ) )
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) )
def _extract_pickup(response: Element, settings: Settings) -> PickupDetails: pickup = ModifyPUResponse() pickup.build(response) pickup_charge = ( ChargeDetails( name="Pickup Charge", amount=NF.decimal(pickup.PickupCharge), currency=pickup.CurrencyCode, ) if pickup.PickupCharge is not None else None ) pickup_date = ( DF.fdate(pickup.NextPickupDate) if pickup.NextPickupDate is not None else None ) return PickupDetails( carrier_name=settings.carrier_name, carrier_id=settings.carrier_id, confirmation_number=str(pickup.ConfirmationNumber[0]), pickup_date=pickup_date, pickup_charge=pickup_charge, ready_time=DF.ftime(pickup.ReadyByTime), closing_time=DF.ftime(pickup.CallInTime), )
def _extract_pickup_details( response: PickupCreationResponse, settings: Settings ) -> PickupDetails: pickup = XP.build( PickupCreationResponse, next( iter( response.xpath( ".//*[local-name() = $name]", name="PickupCreationResponse" ) ), None, ), ) rate = XP.build( RateResultType, next( iter(response.xpath(".//*[local-name() = $name]", name="RateResult")), None ), ) return PickupDetails( carrier_id=settings.carrier_id, carrier_name=settings.carrier_name, confirmation_number=pickup.PRN, pickup_charge=ChargeDetails( name=rate.RateType, currency=rate.CurrencyCode, amount=NF.decimal(rate.GrandTotalOfAllCharge), ), )
def apply(rate: Rate) -> Rate: applicable = [] if any(self.carriers or []): applicable.append(rate.carrier_name in self.carriers) if any(self.services or []): applicable.append(rate.service in self.services) if self.discount_range is not None: applicable.append( rate.discount in cast(NumericRange, self.discount_range)) if self.freight_range is not None: applicable.append(rate.total_charge in cast( NumericRange, self.freight_range)) if any(applicable) and all(applicable): logger.debug('applying broker surcharge to rates') return Rate( **{ **DP.to_dict(rate), 'total_charge': NF.decimal(rate.total_charge + cast(float, self.amount)), 'extra_charges': (rate.extra_charges + [ ChargeDetails(name=cast(str, self.name), amount=cast(float, self.amount), currency=rate.currency) ]) }) return rate
def value(self): sides = [self._side1.CM, self._side2.CM, self._side3.CM] if not any(sides): return None sides.sort() small_side1, small_side2, _ = sides return NF.decimal((small_side1 + small_side2) * 2)
def apply(rate: Rate) -> Rate: applicable = [] carrier_ids = [c.carrier_id for c in self.carrier_accounts.all()] if any(self.carriers or []): applicable.append(rate.carrier_name in self.carriers) if any(carrier_ids): applicable.append(rate.carrier_id in carrier_ids) if any(self.services or []): applicable.append(rate.service in self.services) if self.discount_range is not None: applicable.append(rate.discount in cast(NumericRange, self.discount_range)) if self.freight_range is not None: applicable.append(rate.total_charge in cast(NumericRange, self.freight_range)) if any(applicable) and all(applicable): logger.debug('applying broker surcharge to rate') amount = NF.decimal( self.amount if self.surcharge_type == 'AMOUNT' else (rate.total_charge * (cast(float, self.amount) / 100)) ) base_charge = NF.decimal(rate.base_charge + amount) total_charge = NF.decimal(rate.total_charge + amount) extra_charges = (rate.extra_charges + [ ChargeDetails( name=cast(str, self.name), amount=amount, currency=rate.currency ) ]) return Rate(**{ **DP.to_dict(rate), 'base_charge': base_charge, 'total_charge': total_charge, 'extra_charges': extra_charges }) return rate
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))
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))
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) ) )
def _extract_pickup_details(response: Element, settings: Settings) -> PickupDetails: pickup = XP.find( "PickupCreationResponse", response, PickupCreationResponse, first=True ) rate = XP.find("RateResult", response, RateResultType, first=True) return PickupDetails( carrier_id=settings.carrier_id, carrier_name=settings.carrier_name, confirmation_number=pickup.PRN, pickup_charge=ChargeDetails( name=rate.RateType, currency=rate.CurrencyCode, amount=NF.decimal(rate.GrandTotalOfAllCharge), ), )
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))
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=NF.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, transit_days=cast( service_standardType, price_quote.service_standard ).expected_transit_time, service=ServiceType(price_quote.service_code).name, base_charge=NF.decimal(price_quote.price_details.base or 0), total_charge=NF.decimal(price_quote.price_details.due or 0), discount=NF.decimal(reduce(lambda total, d: total + d.amount, discounts, 0.0)), duties_and_taxes=NF.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=NF.decimal(a.adjustment_cost or 0), ), price_quote.price_details.adjustments.adjustment, ) ), )
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)))
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=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 ] 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=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), )
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))
def shipment_request(payload: ShipmentRequest, _) -> Serializable[NonContractShipmentType]: package = Packages(payload.parcels, PackagePresets, required=["weight"]).single service = ServiceType[payload.service].value options = Options(payload.options, OptionCode) is_intl = (payload.recipient.country_code is not None and payload.recipient.country_code != 'CA') all_options = ([*options] + [(OptionCode.canadapost_return_to_sender.name, OptionCode.canadapost_return_to_sender.value.apply(True))] if is_intl and not any(key in options for key in INTERNATIONAL_NON_DELIVERY_OPTION) else [*options]) request = NonContractShipmentType( requested_shipping_point=None, delivery_spec=DeliverySpecType( service_code=service, sender=SenderType( name=payload.shipper.person_name, company=payload.shipper.company_name, contact_phone=payload.shipper.phone_number, address_details=DomesticAddressDetailsType( address_line_1=SF.concat_str(payload.shipper.address_line1, join=True), address_line_2=SF.concat_str(payload.shipper.address_line2, join=True), city=payload.shipper.city, prov_state=payload.shipper.state_code, postal_zip_code=payload.shipper.postal_code, ), ), destination=DestinationType( name=payload.recipient.person_name, company=payload.recipient.company_name, additional_address_info=None, client_voice_number=payload.recipient.phone_number, address_details=DestinationAddressDetailsType( address_line_1=SF.concat_str( payload.recipient.address_line1, join=True), address_line_2=SF.concat_str( payload.recipient.address_line2, join=True), city=payload.recipient.city, prov_state=payload.recipient.state_code, country_code=payload.recipient.country_code, postal_zip_code=payload.recipient.postal_code, ), ), options=(optionsType(option=[ OptionType( option_code=getattr(option, 'key', option), option_amount=getattr(option, 'value', None), option_qualifier_1=None, option_qualifier_2=None, ) for code, option in all_options if code in OptionCode ]) if any(options) else None), parcel_characteristics=ParcelCharacteristicsType( weight=NF.decimal(package.weight.KG, .1), dimensions=dimensionsType( length=NF.decimal(package.length.CM, .1), width=NF.decimal(package.width.CM, .1), height=NF.decimal(package.height.CM, .1), ), unpackaged=None, mailing_tube=None, ), notification=(NotificationType( email=options.notification_email or payload.recipient.email, on_shipment=True, on_exception=True, on_delivery=True, ) if options.notification_email is not None else None), preferences=PreferencesType( show_packing_instructions=False, show_postage_rate=True, show_insured_value=("insurance" in payload.options), ), references=ReferencesType( cost_centre=None, customer_ref_1=payload.reference, customer_ref_2=None, ), customs=(CustomsType( currency=Currency.AUD.value, conversion_from_cad=None, reason_for_export=payload.customs.incoterm, other_reason=payload.customs.content_description, duties_and_taxes_prepaid=payload.customs.duty.account_number, certificate_number=None, licence_number=None, invoice_number=None, sku_list=sku_listType(item=[ SkuType( customs_number_of_units=item.quantity, customs_description=item.description, sku=item.sku, hs_tariff_code=None, unit_weight=WeightUnit.KG.value, customs_value_per_unit=item.value_amount, customs_unit_of_measure=None, country_of_origin=payload.shipper.country_code, province_of_origin=None, ) for item in payload.customs.commodities ]), ) if payload.customs is not None else None), settlement_info=None, ), ) return Serializable(request, _request_serializer)