Guest User

Untitled

a guest
Nov 22nd, 2017
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.40 KB | None | 0 0
  1. """
  2. Place this file at the root of scurri and then from the console you can:
  3. from get_labels_for_upis import get_pdfs
  4.  
  5. get_pdfs('optional_output_path')
  6.  
  7. The UPIs must be an array:
  8. ['UPI000001',
  9. 'UPI000002',
  10. ...
  11. 'UPIXXXXXX'
  12. ]
  13.  
  14. TOTAL_UPIS must have the number of expected UPIs as a check that the data
  15. is right
  16.  
  17. At the end a file with a PDF will be created at the specified output path.
  18. Defaults to /tmp
  19. """
  20. from __future__ import absolute_import, division, unicode_literals
  21.  
  22. from datetime import date
  23. import logging
  24. import sys
  25.  
  26. from django.template import Context
  27. from django.utils import timezone
  28.  
  29. from sculib.pdf.merge import merge_pdfs
  30. from scurri.carriers.labels import MultiDocumentLabel
  31. from scurri.core.text import wrap_text
  32. from scurri.postmanifest import models
  33.  
  34. logger = logging.getLogger(__name__)
  35.  
  36. UPIS = []
  37. TOTAL_UPIS = 0
  38.  
  39.  
  40. class ParcelNotFound(Exception): # Used internally
  41. pass
  42.  
  43.  
  44. def _find_parcels_by_upi(upi, carrier=None, user=None):
  45. for Parcel in models.PARCEL_MODELS.itervalues():
  46. qs = Parcel.objects
  47. if carrier:
  48. qs = qs.filter(consignment__carrier=carrier)
  49. elif user:
  50. qs = qs.filter(consignment__carrier__members=user)
  51.  
  52. parcels = (
  53. qs.filter(consignment__consignment_number=upi).select_related(
  54. 'consignment',
  55. 'consignment__carrier',
  56. 'consignment__recipient'))
  57.  
  58. for parcel in parcels:
  59. yield parcel
  60.  
  61.  
  62. def _make_label(parcels):
  63. context = _get_context(parcels)
  64.  
  65. label = MultiDocumentLabel(
  66. template='postmanifest/labels/fastway.html', context=context)
  67. return label
  68.  
  69.  
  70. def _get_context(parcels):
  71.  
  72. try:
  73. # We might have >1 parcels with same barcode
  74. # In this case, we need to warn the user
  75. parcel = parcels[0]
  76.  
  77. except IndexError:
  78. raise ParcelNotFound()
  79.  
  80. consignment = parcel.consignment
  81. recipient = consignment.recipient
  82. retailer = consignment.retailer
  83.  
  84. if parcel.state.diverted:
  85. carrier_name = 'ParcelConnect'
  86. else:
  87. # todo: include service name?
  88. carrier_name = 'Fastway'
  89.  
  90. now = timezone.now()
  91. edd = _get_expected_delivery_date(parcel, now=now)
  92. return Context({
  93. 'carrier_name': carrier_name,
  94.  
  95. # 'comments': ['No Comments', 'to display'],
  96. 'consignment_number': consignment.order_number,
  97.  
  98. # FIXME: return correct data in the datamatrix
  99. # FIXME: Use 4W1C barcode + length specifier to allow newlines
  100. 'datamatrix_data': _format_datamatrix(parcel),
  101.  
  102. # Fixme: each row should be 30 char. max length
  103. 'delivery_address': _format_address(recipient),
  104. 'delivery_country': recipient.country,
  105.  
  106. 'delivery_mobile_phone': recipient.mobile,
  107. 'delivery_phone_number': recipient.phone,
  108. # 'delivery_state': 'STATE', # TODO: what needs to go here?
  109. 'delivery_date': now,
  110. 'expected_delivery_date': edd,
  111. 'recipient_name': recipient.name,
  112. # 'service_name': 'SERVICE', # TODO: how to get this? do we need it? # noqa
  113. 'tracking_number': parcel.tracking_number,
  114. 'warehouse_address': _format_address(
  115. retailer, with_country=True),
  116. 'warehouse_phone_number': '', # TODO: how to get this?
  117. 'weight': parcel.weight,
  118. 'weight_unit': 'kg',
  119.  
  120. 'item_id': parcel.index,
  121. 'item_total': consignment.parcels.count(),
  122. })
  123.  
  124.  
  125. def _format_address(addr, with_country=False):
  126. address = ', '.join(filter(None, [
  127. addr.address1,
  128. addr.address2,
  129. addr.address3,
  130. addr.address4,
  131. addr.postcode,
  132. addr.country if with_country else None,
  133. ]))
  134. return wrap_text(address, max_line_width=30, number_of_lines=4)
  135.  
  136.  
  137. def _get_expected_delivery_date(parcel, now=None):
  138. from scurri.postmanifest.io.targets.fastway import get_expected_delivery_date # noqa
  139.  
  140. try:
  141. return get_expected_delivery_date(parcel=parcel, scan_date=now)
  142. except Exception:
  143. logger.exception('Failure calculating expected delivery date')
  144. return None
  145.  
  146.  
  147. def _format_datamatrix(parcel):
  148. # todo: do we want pipes as a separator, or we just need to use
  149. # a different DPL code to support newlines?
  150. recipient = parcel.consignment.recipient
  151. return ' | '.join((
  152. recipient.name or '',
  153. '', # intentionally left blank - Building Name should go here
  154. recipient.address1 or '',
  155. recipient.address2 or '',
  156. recipient.address3 or '',
  157. recipient.address4 or '',
  158. recipient.postcode or '',
  159. recipient.phone or '',
  160. '',
  161. recipient.name or '',
  162. ))
  163.  
  164.  
  165. def _make_pdf(parcels):
  166. label = _make_label(parcels)
  167. return label
  168.  
  169.  
  170. def get_pdfs(output_path='/tmp'):
  171. if TOTAL_UPIS <= 0:
  172. raise Exception('Amend the UPIS and TOTAL_UPIS, please')
  173.  
  174. carrier = models.Carrier.objects.get(name='Fastway')
  175. pdfs = []
  176.  
  177. assert len(UPIS) == TOTAL_UPIS # Check that numbers are valid
  178.  
  179. for upi in UPIS:
  180. parcels = list(_find_parcels_by_upi(upi, carrier=carrier))
  181. pdfs.append(_make_pdf(parcels))
  182.  
  183. total_pdfs = len(pdfs)
  184. output_filename = '/'.join([output_path,
  185. date.today().isoformat() + '-' + 'labels.pdf'])
  186.  
  187. sys.stdout.write('{} labels generated and stored in {}'.format(
  188. total_pdfs, output_filename))
  189.  
  190. pdfs = merge_pdfs(pdfs)
  191.  
  192. with open(output_filename, b'wb') as f:
  193. f.writelines(pdfs.getvalue())
Add Comment
Please, Sign In to add comment