Exemple #1
0
def _extract_details(node: Element, settings) -> TrackingDetails:
    info = XP.to_object(TrackInfoType, node)
    details: List[TrackDetailType] = [
        *([info.TrackSummary] or []), *info.TrackDetail
    ]
    delivered = info.StatusCategory.lower() == "delivered"

    return TrackingDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           tracking_number=info.ID,
                           events=[
                               TrackingEvent(
                                   code=str(event.EventCode),
                                   date=DF.fdate(event.EventDate, "%B %d, %Y"),
                                   time=DF.ftime(event.EventTime, "%H:%M %p"),
                                   description=event.Event,
                                   location=", ".join([
                                       location for location in [
                                           event.EventCity,
                                           event.EventState,
                                           event.EventCountry,
                                           str(event.EventZIPCode),
                                       ] if location is not None
                                   ]),
                               ) for event in details
                           ],
                           delivered=delivered)
def _extract_tracking(
    track_detail_node: Element, settings: Settings
) -> Optional[TrackingDetails]:
    track_detail = TrackDetail()
    track_detail.build(track_detail_node)
    if track_detail.Notification.Severity == "ERROR":
        return None

    delivered = any(e.EventType == 'DL' for e in track_detail.Events)

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=track_detail.TrackingNumber,
        events=list(
            map(
                lambda e: TrackingEvent(
                    date=DF.fdate(e.Timestamp, "%Y-%m-%d %H:%M:%S%z"),
                    time=DF.ftime(e.Timestamp, "%Y-%m-%d %H:%M:%S%z"),
                    code=e.EventType,
                    location=e.ArrivalLocation,
                    description=e.EventDescription,
                ),
                track_detail.Events,
            )
        ),
        delivered=delivered
    )
Exemple #3
0
def _extract_tracking_details(node: Element,
                              settings: Settings) -> TrackingDetails:
    result = XP.build(TrackingResult, node)
    is_en = settings.language == "en"
    events = [
        TrackingEvent(
            date=DF.fdate(event.local_date_time, '%Y%m%d %H%M%S'),
            description=(event.code_description_en
                         if is_en else event.code_description_fr),
            location=SF.concat_str(event.address.address_line_1,
                                   event.address.address_line_2,
                                   event.address.city,
                                   event.address.province,
                                   event.address.country,
                                   join=True,
                                   separator=", "),
            code=event.code,
            time=DF.ftime(event.local_date_time, '%Y%m%d %H%M%S'),
        ) for event in cast(List[CanparTrackingEvent], result.events)
    ]

    return TrackingDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           tracking_number=result.barcode,
                           events=events,
                           delivered=any(event.code == 'DEL'
                                         for event in events))
Exemple #4
0
def _extract_tracking(
    info_node: Element, settings: Settings
) -> Optional[TrackingDetails]:
    info = AWBInfo()
    info.build(info_node)
    if info.ShipmentInfo is None:
        return None

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=info.AWBNumber,
        events=list(
            map(
                lambda e: TrackingEvent(
                    date=DF.fdate(e.Date),
                    time=DF.ftime(e.Time),
                    signatory=e.Signatory,
                    code=e.ServiceEvent.EventCode,
                    location=e.ServiceArea.Description,
                    description=e.ServiceEvent.Description,
                ),
                info.ShipmentInfo.ShipmentEvent,
            )
        ),
    )
Exemple #5
0
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,
    )
Exemple #6
0
def _extract_details(shipment_node: Element,
                     settings: Settings) -> TrackingDetails:
    track_detail = XP.build(ShipmentType, shipment_node)
    activities = [
        XP.build(ActivityType, node)
        for node in shipment_node.xpath(".//*[local-name() = $name]",
                                        name="Activity")
    ]
    delivered = any(a.Status.Type == 'D' for a in activities)

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=track_detail.InquiryNumber.Value,
        events=list(
            map(
                lambda a: TrackingEvent(
                    date=DF.fdate(a.Date, "%Y%m%d"),
                    description=a.Status.Description if a.Status else None,
                    location=(_format_location(a.ActivityLocation.Address)
                              if a.ActivityLocation is not None and a.
                              ActivityLocation.Address is not None else None),
                    time=DF.ftime(a.Time, "%H%M%S"),
                    code=a.Status.Code if a.Status else None,
                ),
                activities,
            )),
        delivered=delivered)
Exemple #7
0
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_detail(detail: Tracking, settings: Settings) -> TrackingDetails:
    return TrackingDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           tracking_number=detail.trackingNumber,
                           events=[
                               TrackingEvent(
                                   date=DF.fdate(event.activityDate,
                                                 '%Y-%m-%dT%H:%M:%SZ'),
                                   description=event.statusDetail,
                                   location=event.terminal,
                                   code=event.status,
                                   time=DF.ftime(event.activityDate,
                                                 '%Y-%m-%dT%H:%M:%SZ'),
                               ) for event in detail.activities
                           ])
Exemple #9
0
def _extract_detail(detail: MailPieces, settings: Settings) -> TrackingDetails:

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=detail.mailPieceId,
        events=[
            TrackingEvent(
                date=DF.fdate(event.eventDateTime, '%Y-%m-%dT%H:%M:%S%z'),
                description=event.eventName,
                location=event.locationName,
                code=event.eventCode,
                time=DF.ftime(event.eventDateTime, '%Y-%m-%dT%H:%M:%S%z'),
            ) for event in detail.events
        ],
    )
Exemple #10
0
def _extract_detail(detail: RouteResp, settings: Settings) -> TrackingDetails:

    return TrackingDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           tracking_number=detail.mailNo,
                           events=[
                               TrackingEvent(
                                   date=DF.fdate(event.acceptTime,
                                                 "%Y-%m-%d %H:%M:%S"),
                                   description=event.remark,
                                   location=event.acceptAddress,
                                   code=event.opCode,
                                   time=DF.ftime(event.acceptTime,
                                                 "%Y-%m-%d %H:%M:%S"),
                               ) for event in detail.routes
                           ])
Exemple #11
0
def _extract_detail(detail: dict, settings: Settings) -> TrackingDetails:
    result = DP.to_object(Result, detail)
    return TrackingDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           tracking_number=result.tracking_number,
                           events=[
                               TrackingEvent(
                                   date=DF.fdate(event.time_stamp,
                                                 '2019-08-15T18:52:19'),
                                   description=event.message,
                                   location=event.location,
                                   code=event.tracking_status,
                                   time=DF.ftime(event.time_stamp,
                                                 '2019-08-15T18:52:19'),
                               ) for event in result.checkpoints
                           ],
                           delivered=(result.tracking_status == 'LM40'))
Exemple #12
0
def _extract_detail(detail: Shipment, settings: Settings) -> TrackingDetails:
    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=str(detail.id),
        events=[
            TrackingEvent(
                date=DF.fdate(event.timestamp, '%Y-%m-%dT%H:%M:%S'),
                description=event.description,
                location=(event.location.address.addressLocality
                          if event.location is not None
                          and event.location.address is not None else None),
                code=event.statusCode,
                time=DF.ftime(event.timestamp, '%Y-%m-%dT%H:%M:%S'),
            ) for event in detail.events
        ],
        delivered=detail.status.status.lower() == "delivered")
Exemple #13
0
def _extract_detail(detail: Tuple[str, Tracking],
                    settings: Settings) -> TrackingDetails:
    tracking_number, tracking_details = detail

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=tracking_number,
        events=[
            TrackingEvent(
                date=DF.fdate(event.scan_time, '%Y-%m-%dT%H:%M:%SZ'),
                description=event.description,
                location=event.location,
                code=event.event_type,
                time=DF.ftime(event.scan_time, '%Y-%m-%dT%H:%M:%SZ'),
            ) for event in reversed(tracking_details.tracking_events)
        ],
        delivered=(tracking_details.state == 'Delivered'))
Exemple #14
0
def _extract_detail(detail: TrackingResult, settings: Settings) -> TrackingDetails:
    item = detail.trackable_items[0]

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

        tracking_number=detail.tracking_id,
        events=[
            TrackingEvent(
                date=DF.fdate(event.date, '%Y-%m-%dT%H:%M:%S%z'),
                description=event.description,
                location=event.location,
                time=DF.ftime(event.date, '%Y-%m-%dT%H:%M:%S%z'),
            ) for event in item.events
        ],
        delivered=(detail.status == 'Delivered')
    )
Exemple #15
0
def _extract_tracking(node: Element, settings: Settings) -> TrackingDetails:
    track = TrackingInformation()
    track.build(node)
    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=str(track.PIN.Value),
        events=[
            TrackingEvent(
                date=DF.fdate(cast(Scan, scan).ScanDate),
                time=DF.ftimestamp(cast(Scan, scan).ScanTime),
                description=cast(Scan, scan).Description,
                location=cast(Depot,
                              cast(Scan, scan).Depot).Name,
                code=cast(Scan, scan).ScanType,
            ) for scan in track.Scans.Scan
        ],
    )
def _extract_tracking(node: Element, settings: Settings) -> TrackingDetails:
    track = XP.to_object(TrackingInformation, node)

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=str(track.PIN.Value),
        events=[
            TrackingEvent(
                date=DF.fdate(scan.ScanDate),
                time=DF.ftime(scan.ScanTime, '%H%M%S'),
                description=scan.Description,
                location=scan.Depot.Name,
                code=scan.ScanType,
            )
            for scan in track.Scans.Scan
        ],
        delivered=any(scan.ScanType == "Delivery" for scan in track.Scans.Scan)
    )
Exemple #17
0
def _extract_tracking(pin_summary_node: Element,
                      settings: Settings) -> TrackingDetails:
    pin_summary_ = pin_summary()
    pin_summary_.build(pin_summary_node)
    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=pin_summary_.pin,
        events=[
            TrackingEvent(
                date=DF.fdate(pin_summary_.event_date_time, "%Y%m%d:%H%M%S"),
                time=DF.ftime(pin_summary_.event_date_time, "%Y%m%d:%H%M%S"),
                signatory=pin_summary_.signatory_name,
                code=pin_summary_.event_type,
                location=pin_summary_.event_location,
                description=pin_summary_.event_description,
            )
        ],
    )
Exemple #18
0
def _extract_tracking(detail_node: Element, settings: Settings) -> TrackingDetails:
    pin = XP.find("pin", detail_node, first=True)
    events: List[occurrenceType] = XP.find("occurrence", detail_node, occurrenceType)

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=pin.text,
        events=[
            TrackingEvent(
                date=DF.fdate(event.event_date, "%Y-%m-%d"),
                time=DF.ftime(event.event_time, "%H:%M:%S"),
                code=event.event_identifier,
                location=SF.concat_str(event.event_site, event.event_province, join=True, separator=', '),
                description=event.event_description
            )
            for event in events
        ],
        delivered=any(e.event_identifier in TRACKING_DELIVERED_EVENT_CODES for e in events)
    )
Exemple #19
0
def _extract_detail(node: Element, settings: Settings) -> TrackingDetails:
    detail = XP.build(ConsignmentType, node)

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

        tracking_number=detail.ConsignmentNumber,
        events=[
            TrackingEvent(
                date=DF.fdate(status.LocalEventDate.valueOf_, '%Y%m%d'),
                description=status.StatusDescription,
                location=SF.concat_str(status.Depot, status.DepotName, join=True, separator='-'),
                code=status.StatusCode,
                time=DF.ftime(status.LocalEventTime.valueOf_, '%H%M')
            )
            for status in cast(List[StatusStructure], detail.StatusData)
        ],
        delivered=(detail.SummaryCode == "DEL")
    )
Exemple #20
0
def _extract_detail(detail: dict, settings: Settings) -> TrackingDetails:
    tracking = DP.to_object(Tracking, detail)
    delivered = (tracking.trackingMilestoneEvents[0].eventCode == 'Delivered'
                 if len(tracking.trackingMilestoneEvents) > 0 else False)

    return TrackingDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           tracking_number=tracking.trackingNumberVendor,
                           events=[
                               TrackingEvent(
                                   date=DF.fdate(event.eventOn,
                                                 _date_format(event.eventOn)),
                                   time=DF.ftime(event.eventOn,
                                                 _date_format(event.eventOn)),
                                   description=event.eventDescription,
                                   location=event.eventLocation,
                                   code=event.eventCode,
                               ) for event in tracking.trackingMilestoneEvents
                           ],
                           delivered=delivered)
def _extract_tracking_details(infos: Tuple[str, TrackingInfo],
                              settings: Settings) -> TrackingDetails:
    tracking_number, events = infos
    ordered_events = [
        *reversed(
            sorted(events,
                   key=lambda e: DF.date(e.StatusDate, "%Y-%m-%dT%H:%M:%S")))
    ]

    return TrackingDetails(carrier_name=settings.carrier_name,
                           carrier_id=settings.carrier_id,
                           tracking_number=tracking_number,
                           events=[
                               TrackingEvent(
                                   date=DF.fdate(event.StatusDate,
                                                 "%Y-%m-%dT%H:%M:%S"),
                                   time=DF.ftime(event.StatusDate,
                                                 "%Y-%m-%dT%H:%M:%S"),
                                   description=event.Status,
                               ) for event in ordered_events
                           ],
                           delivered=('Delivered' in ordered_events[0].Status))
Exemple #22
0
def _extract_tracking(info_node: Element,
                      settings: Settings) -> Optional[TrackingDetails]:
    tracking_number = XP.find('AWBNumber', info_node, first=True).text
    events: List[ShipmentEvent] = XP.find('ShipmentEvent', info_node,
                                          ShipmentEvent)
    delivered = any(e.ServiceEvent.EventCode == 'OK' for e in events)

    return TrackingDetails(
        carrier_name=settings.carrier_name,
        carrier_id=settings.carrier_id,
        tracking_number=tracking_number,
        events=[
            TrackingEvent(
                date=DF.fdate(e.Date),
                time=DF.ftime(e.Time),
                code=e.ServiceEvent.EventCode,
                location=e.ServiceArea.Description,
                description=f'{e.ServiceEvent.Description} {e.Signatory}'.
                strip(),
            ) for e in reversed(events)
        ],
        delivered=delivered)
def create_shipment_tracker(shipment: Optional[models.Shipment], context):
    rate_provider = (shipment.meta
                     or {}).get("rate_provider") or shipment.carrier_name
    carrier = shipment.selected_rate_carrier

    if (rate_provider != shipment.carrier_name) and rate_provider in MODELS:
        carrier = (MODELS[rate_provider].access_by(context).filter(
            test=shipment.test_mode).first())

    if carrier is not None:
        try:
            tracker = models.Tracking.objects.create(
                tracking_number=shipment.tracking_number,
                events=[
                    DP.to_dict(
                        datatypes.TrackingEvent(
                            date=DF.fdate(shipment.updated_at),
                            description="Label created and ready for shipment",
                            location="",
                            code="CREATED",
                            time=DF.ftime(shipment.updated_at),
                        ))
                ],
                delivered=False,
                status=TrackerStatus.pending.value,
                test_mode=carrier.test,
                tracking_carrier=carrier,
                created_by=shipment.created_by,
                shipment=shipment,
            )
            tracker.save()
            link_org(tracker, context)
            logger.info(
                f"Successfully added a tracker to the shipment {shipment.id}")
        except Exception as e:
            logger.exception("Failed to create new label tracker", e)
Exemple #24
0
def rate_request(payload: RateRequest,
                 settings: Settings) -> Serializable[RateV4Request]:
    """Create the appropriate USPS rate request depending on the destination

    :param payload: Purplship unified API rate request data
    :param settings: USPS connection and auth settings
    :return: a domestic or international USPS compatible request
    :raises: an OriginNotServicedError when origin country is not serviced by the carrier
    """

    if payload.shipper.country_code is not None and payload.shipper.country_code != Country.US.name:
        raise OriginNotServicedError(payload.shipper.country_code)

    if payload.recipient.country_code is not None and payload.recipient.country_code == Country.US.name:
        raise DestinationNotServicedError(payload.recipient.country_code)

    package = Packages(payload.parcels).single
    options = Options(payload.options, ShipmentOption)
    service = (Services(payload.services, ShipmentService).first
               or ShipmentService.usps_all)
    special_services = [
        getattr(option, 'value', option) for key, option in options
        if 'usps_option' not in key
    ]
    insurance = next(
        (option.value for key, option in options if 'usps_insurance' in key),
        options.insurance)

    container = PackagingType[package.packaging_type or "your_packaging"]
    sort_level = (SortLevelType[container.name].value
                  if service.value in ["All", "Online"] else None)
    mail_type = (FirstClassMailType[container.name].value
                 if 'first_class' in service.value else None)

    request = RateV4Request(
        USERID=settings.username,
        Revision="2",
        Package=[
            PackageType(
                ID=0,
                Service=service.value,
                FirstClassMailType=mail_type,
                ZipOrigination=payload.shipper.postal_code,
                ZipDestination=payload.recipient.postal_code,
                Pounds=package.weight.LB,
                Ounces=package.weight.OZ,
                Container=container.value,
                Width=package.width.IN,
                Length=package.length.IN,
                Height=package.height.IN,
                Girth=package.girth.value,
                Value=insurance,
                AmountToCollect=options.cash_on_delivery,
                SpecialServices=(SpecialServicesType(
                    SpecialService=[s for s in special_services])
                                 if any(special_services) else None),
                Content=None,
                GroundOnly=options.usps_option_ground_only,
                SortBy=sort_level,
                Machinable=(options.usps_option_machinable_item or False),
                ReturnLocations=options.usps_option_return_service_info,
                ReturnServiceInfo=options.usps_option_return_service_info,
                DropOffTime=('13:30'
                             if options.shipment_date is not None else None),
                ShipDate=(ShipDateType(
                    valueOf_=DF.fdate(options.shipment_date))
                          if options.shipment_date is not None else None),
            )
        ],
    )

    return Serializable(request, XP.export)