예제 #1
0
def create_envelope(
    body_content: Element,
    header_content: Element = None,
    header_prefix: str = None,
    body_prefix: str = None,
    header_tag_name: str = None,
    body_tag_name: str = None,
    envelope_prefix: str = "tns",
) -> Envelope:
    header = None
    if header_content is not None:
        header_content.ns_prefix_ = header_prefix or header_content.ns_prefix_
        header_content.original_tagname_ = (header_tag_name or
                                            header_content.original_tagname_)
        header = Header()
        header.add_anytypeobjs_(header_content)

    body_content.ns_prefix_ = body_prefix or body_content.ns_prefix_
    body_content.original_tagname_ = body_tag_name or body_content.original_tagname_
    body = Body()
    body.add_anytypeobjs_(body_content)

    envelope = Envelope(Header=header, Body=body)
    envelope.ns_prefix_ = envelope_prefix
    envelope.Body.ns_prefix_ = envelope.ns_prefix_
    if envelope.Header is not None:
        envelope.Header.ns_prefix_ = envelope.ns_prefix_
    return envelope
예제 #2
0
def export(xml_element: Element, **kwds) -> str:
    """Return a XML string.

    invoke the export method of generated type to return the subsequent XML represented
    """
    output = io.StringIO()
    xml_element.export(output, 0, **kwds)
    return output.getvalue()
예제 #3
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)
    )
예제 #4
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)
예제 #5
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)
예제 #6
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
    ]
예제 #7
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)
예제 #8
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),
    )
예제 #9
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),
    )
예제 #10
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
    ]
예제 #11
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
    ]
예제 #12
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,
    )
예제 #13
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),
            )
        ]
예제 #14
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]
예제 #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)
예제 #16
0
파일: error.py 프로젝트: iliaaz/purplship
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)
예제 #17
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, [])