Exemplo n.º 1
0
def parse_error_response(response: Element, settings: Settings) -> List[Message]:
    notifications = (
            response.xpath(".//*[local-name() = $name]", name="Notifications") +
            response.xpath(".//*[local-name() = $name]", name="Notification")
    )
    return reduce(
        _extract_error(settings), notifications,
        extract_fault(response, settings)
    )
Exemplo n.º 2
0
def parse_shipment_response(
    response: Element, settings: Settings
) -> Tuple[ShipmentDetails, List[Message]]:
    details = next(
        iter(response.xpath(".//*[local-name() = $name]", name="ShipmentResults")), None
    )
    shipment = _extract_shipment(details, settings) if details is not None else None
    return shipment, parse_error_response(response, settings)
Exemplo n.º 3
0
def parse_freight_ship_response(
        response: Element,
        settings: Settings) -> Tuple[ShipmentDetails, List[Message]]:
    details = response.xpath(".//*[local-name() = $name]",
                             name="FreightShipResponse")
    shipment = _extract_shipment(details[0],
                                 settings) if len(details) > 0 else None
    return shipment, parse_error_response(response, settings)
Exemplo n.º 4
0
def parse_freight_rate_response(
        response: Element,
        settings: Settings) -> Tuple[List[RateDetails], List[Message]]:
    rate_reply = response.xpath(".//*[local-name() = $name]",
                                name="FreightRateResponse")
    rates: List[RateDetails] = [
        _extract_freight_rate(detail_node, settings)
        for detail_node in rate_reply
    ]
    return rates, parse_error_response(response, settings)
Exemplo n.º 5
0
def extract_fault(response: Element, settings: Type[Settings]) -> Message:
    faults = [build(Fault, node) for node in response.xpath(".//*[local-name() = $name]", name="Fault")]
    return [
        Message(
            code=fault.faultcode,
            message=fault.faultstring,
            carrier_name=settings.carrier_name,
            carrier_id=settings.carrier_id
        ) for fault in faults
    ]
Exemplo n.º 6
0
def parse_shipment_response(
    response: Element, settings: Settings
) -> Tuple[ShipmentDetails, List[Message]]:
    air_way_bill = next(
        iter(response.xpath(".//*[local-name() = $name]", name="AirwayBillNumber")),
        None,
    )
    return (
        _extract_shipment(response, settings) if air_way_bill is not None else None,
        parse_error_response(response, settings),
    )
Exemplo n.º 7
0
def parse_rate_response(
        response: Element,
        settings: Settings) -> Tuple[List[RateDetails], List[Message]]:
    rate_reply = response.xpath(".//*[local-name() = $name]",
                                name="RateReplyDetails")
    rate_details: List[RateDetails] = [
        _extract_rate(detail_node, settings) for detail_node in rate_reply
    ]
    return (
        [details for details in rate_details if details is not None],
        parse_error_response(response, settings),
    )
Exemplo n.º 8
0
def extract_fault(response: Element, settings: Settings) -> List[Message]:
    faults = [
        XMLPARSER.build(Fault, node)
        for node in response.xpath(".//*[local-name() = $name]", name="Fault")
    ]
    return [
        Message(
            code=fault.faultcode,
            message=fault.faultstring,
            carrier_name=settings.carrier_name,
            carrier_id=settings.carrier_id,
        ) for fault in faults
    ]
Exemplo n.º 9
0
def parse_error_response(response: Element, settings: Settings) -> List[Message]:
    error_nodes: List[Error] = [
        (lambda error: (error, error.build(node)))(Error())[0]
        for node in (
            [response]
            if response.tag == "Error"
            else response.xpath(".//*[local-name() = $name]", name="Error")
        )
    ]
    return [
        Message(
            carrier_name=settings.carrier_name,
            carrier_id=settings.carrier_id,
            code=str(error.Number),
            message=error.Description,
        )
        for error in error_nodes
    ]
Exemplo n.º 10
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,
    )
Exemplo n.º 11
0
def parse_error_response(response: Element,
                         settings: Settings) -> List[Message]:
    notifications = response.xpath(".//*[local-name() = $name]",
                                   name="PrimaryErrorCode")
    return [_extract_error(node, settings) for node in notifications]
Exemplo n.º 12
0
def parse_error_response(response: Element,
                         settings: Settings) -> List[Message]:
    errors = response.xpath(".//*[local-name() = $name]", name="Error")
    return [_extract_error(node, settings)
            for node in errors] + extract_fault(response, settings)
Exemplo n.º 13
0
def parse_error_response(response: Element,
                         settings: Settings) -> List[Message]:
    messages = response.xpath(".//*[local-name() = $name]", name="message")
    return reduce(_extract_error(settings), messages, [])
Exemplo n.º 14
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),
            )
        ]
Exemplo n.º 15
0
def parse_rate_response(
    response: Element, settings: Settings
) -> Tuple[List[RateDetails], List[Message]]:
    rate_reply = response.xpath(".//*[local-name() = $name]", name="RatedShipment")
    rates: List[RateDetails] = reduce(_extract_package_rate(settings), rate_reply, [])
    return rates, parse_error_response(response, settings)