def IN(self): if self._unit is None or self._value is None: return None if self._unit == DimensionUnit.IN: return decimal(self._value) else: return decimal(self._value * 2.54)
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 ], )
def CM(self): if self._unit is None or self._value is None: return None if self._unit == DimensionUnit.CM: return decimal(self._value) else: return decimal(self._value * 0.393701)
def OZ(self): if self._unit is None or self._value is None: return None if self._unit == WeightUnit.LB: return decimal(self._value * 16) elif self._unit == WeightUnit.KG: return decimal(self._value * 35.274) return None
def LB(self): if self._unit is None or self._value is None: return None if self._unit == WeightUnit.LB: return decimal(self._value) elif self._unit == WeightUnit.KG: return decimal(self._value * 2.204620823516057) return None
def KG(self): if self._unit is None or self._value is None: return None if self._unit == WeightUnit.KG: return decimal(self._value) elif self._unit == WeightUnit.LB: return decimal(self._value * 0.453592) return None
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 decimal((small_side1 + small_side2) * 2)
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, )
def _extract_pickup(response: Element, settings: Settings) -> PickupDetails: pickup = BookPUResponse() pickup.build(response) pickup_charge = (ChargeDetails( name="Pickup Charge", amount=decimal(pickup.PickupCharge), currency=pickup.CurrencyCode, ) if pickup.PickupCharge 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=format_date(pickup.NextPickupDate), pickup_charge=pickup_charge, ready_time=format_time(pickup.ReadyByTime), closing_time=format_time(pickup.CallInTime), )
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) delivery_date = to_date(qtdshp.DeliveryDate[0].DlvyDateTime, "%Y-%m-%d %H:%M:%S") pricing_date = to_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 Product if p.value in qtdshp.LocalProductName), qtdshp.LocalProductName, ) return RateDetails( carrier_name=settings.carrier_name, carrier_id=settings.carrier_id, currency=qtdshp.CurrencyCode, transit_days=transit, 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, )), )
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), )
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, ) ), )
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, )
def extract(rates: List[RateDetails], detail_node: Element) -> List[RateDetails]: rate = 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( (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( 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], [], ), transit_days=integer(transit_days), ) ]
def cubic_meter(self): if self.value is None: return None return decimal(self.value * 250)
def M(self): if self._unit is None or self._value is None: return None else: return decimal(self.CM / 100)
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), ) ]
def value(self): if not any([self._side1.value, self._side2.value, self._side3.value]): return None return decimal(self._side1.M * self._side2.M * self._side3.M)