Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Place this file at the root of scurri and then from the console you can:
- from get_labels_for_upis import get_pdfs
- get_pdfs('optional_output_path')
- The UPIs must be an array:
- ['UPI000001',
- 'UPI000002',
- ...
- 'UPIXXXXXX'
- ]
- TOTAL_UPIS must have the number of expected UPIs as a check that the data
- is right
- At the end a file with a PDF will be created at the specified output path.
- Defaults to /tmp
- """
- from __future__ import absolute_import, division, unicode_literals
- from datetime import date
- import logging
- import sys
- from django.template import Context
- from django.utils import timezone
- from sculib.pdf.merge import merge_pdfs
- from scurri.carriers.labels import MultiDocumentLabel
- from scurri.core.text import wrap_text
- from scurri.postmanifest import models
- logger = logging.getLogger(__name__)
- UPIS = []
- TOTAL_UPIS = 0
- class ParcelNotFound(Exception): # Used internally
- pass
- def _find_parcels_by_upi(upi, carrier=None, user=None):
- for Parcel in models.PARCEL_MODELS.itervalues():
- qs = Parcel.objects
- if carrier:
- qs = qs.filter(consignment__carrier=carrier)
- elif user:
- qs = qs.filter(consignment__carrier__members=user)
- parcels = (
- qs.filter(consignment__consignment_number=upi).select_related(
- 'consignment',
- 'consignment__carrier',
- 'consignment__recipient'))
- for parcel in parcels:
- yield parcel
- def _make_label(parcels):
- context = _get_context(parcels)
- label = MultiDocumentLabel(
- template='postmanifest/labels/fastway.html', context=context)
- return label
- def _get_context(parcels):
- try:
- # We might have >1 parcels with same barcode
- # In this case, we need to warn the user
- parcel = parcels[0]
- except IndexError:
- raise ParcelNotFound()
- consignment = parcel.consignment
- recipient = consignment.recipient
- retailer = consignment.retailer
- if parcel.state.diverted:
- carrier_name = 'ParcelConnect'
- else:
- # todo: include service name?
- carrier_name = 'Fastway'
- now = timezone.now()
- edd = _get_expected_delivery_date(parcel, now=now)
- return Context({
- 'carrier_name': carrier_name,
- # 'comments': ['No Comments', 'to display'],
- 'consignment_number': consignment.order_number,
- # FIXME: return correct data in the datamatrix
- # FIXME: Use 4W1C barcode + length specifier to allow newlines
- 'datamatrix_data': _format_datamatrix(parcel),
- # Fixme: each row should be 30 char. max length
- 'delivery_address': _format_address(recipient),
- 'delivery_country': recipient.country,
- 'delivery_mobile_phone': recipient.mobile,
- 'delivery_phone_number': recipient.phone,
- # 'delivery_state': 'STATE', # TODO: what needs to go here?
- 'delivery_date': now,
- 'expected_delivery_date': edd,
- 'recipient_name': recipient.name,
- # 'service_name': 'SERVICE', # TODO: how to get this? do we need it? # noqa
- 'tracking_number': parcel.tracking_number,
- 'warehouse_address': _format_address(
- retailer, with_country=True),
- 'warehouse_phone_number': '', # TODO: how to get this?
- 'weight': parcel.weight,
- 'weight_unit': 'kg',
- 'item_id': parcel.index,
- 'item_total': consignment.parcels.count(),
- })
- def _format_address(addr, with_country=False):
- address = ', '.join(filter(None, [
- addr.address1,
- addr.address2,
- addr.address3,
- addr.address4,
- addr.postcode,
- addr.country if with_country else None,
- ]))
- return wrap_text(address, max_line_width=30, number_of_lines=4)
- def _get_expected_delivery_date(parcel, now=None):
- from scurri.postmanifest.io.targets.fastway import get_expected_delivery_date # noqa
- try:
- return get_expected_delivery_date(parcel=parcel, scan_date=now)
- except Exception:
- logger.exception('Failure calculating expected delivery date')
- return None
- def _format_datamatrix(parcel):
- # todo: do we want pipes as a separator, or we just need to use
- # a different DPL code to support newlines?
- recipient = parcel.consignment.recipient
- return ' | '.join((
- recipient.name or '',
- '', # intentionally left blank - Building Name should go here
- recipient.address1 or '',
- recipient.address2 or '',
- recipient.address3 or '',
- recipient.address4 or '',
- recipient.postcode or '',
- recipient.phone or '',
- '',
- recipient.name or '',
- ))
- def _make_pdf(parcels):
- label = _make_label(parcels)
- return label
- def get_pdfs(output_path='/tmp'):
- if TOTAL_UPIS <= 0:
- raise Exception('Amend the UPIS and TOTAL_UPIS, please')
- carrier = models.Carrier.objects.get(name='Fastway')
- pdfs = []
- assert len(UPIS) == TOTAL_UPIS # Check that numbers are valid
- for upi in UPIS:
- parcels = list(_find_parcels_by_upi(upi, carrier=carrier))
- pdfs.append(_make_pdf(parcels))
- total_pdfs = len(pdfs)
- output_filename = '/'.join([output_path,
- date.today().isoformat() + '-' + 'labels.pdf'])
- sys.stdout.write('{} labels generated and stored in {}'.format(
- total_pdfs, output_filename))
- pdfs = merge_pdfs(pdfs)
- with open(output_filename, b'wb') as f:
- f.writelines(pdfs.getvalue())
Add Comment
Please, Sign In to add comment