def generate_csv(orders):
"""
Generate a consignment CSV from a list of orders
Parameters:
orders - The list of orders to work with
Returns:
An iterable that contains every (\\n terminated) line of the CSV as a string.
"""
for order in orders:
# Each order from Shopify needs a Consignment line, and one or more
# Article line per physical parcel being sent. Goods being sent
# overseas need one Goods line per Article line to pass customs.
# Additionally, overseas consignments can only have one
# article/physical parcel. To simplify things, we simply print one
# consignment, article and goods line per order. This will work in
# all instances.
#
# See `docs/eParcel Consignment Import Guide.pdf`, page 8 for more
# information
dest = order.shipping_address
# International consignments have different requirements
international = dest.country_code != settings.COUNTRY_CODE
weight_in_grams = int(order.total_weight) or settings.EPARCEL_DEFAULT_WEIGHT
weight = "%0.2f" % (weight_in_grams / 1000.0)
price = "%0.2f" % float(order.total_price)
item_count = sum([int(i.quantity) for i in order.line_items])
data = [
( # Consignment line
'C',
# B-D
'', # Must be left blank
settings.EPARCEL_ACCOUNT_NUMBER, # Optional, may be blank
settings.EPARCEL_CHARGE_CODE['international' if international else 'domestic'],
# E-F: Create a new consignee
'',
dest.name,
# G-O: Shipping address
dest.company or '',
dest.address1 or '',
dest.address2 or '',
'', # address line 3
'', # address line 4
dest.city,
dest.province_code,
dest.zip,
dest.country_code,
# P: Required for international consignments
# TODO This is terrible
dest.phone or '555 1234',
# Q-S: Display phone; fax number; special instructions
'',
'',
'',
'N', # T: No signature required
'', # U: Part delivery
'', # V: No comments
'N', # W: Do not add consignee to address book
),
( # Article line
'A',
weight, # B: Weight of this article (sum of all weights)
'', '', '', # C-E: Length; width; height;
item_count, # F: Number of articles
'Clothing', # G: Article description. What should go here?
'N', # H: Goods are NOT dangerous
'N', '', '', # I-K: Insurance is not required
),
]
if international:
data.append(( # Goods line
'G',
# B: Shipping from this country
settings.COUNTRY_CODE,
# C: HS Tarrif code. Dunno what this is?
'',
# D: Description
'Clothing',
'', # E: Product type
settings.EPARCEL_PRODUCT_CLASSIFICATION, # F
# G-H: Quantity and weight
item_count, weight,
# I-J: Unit value; total value.
price, price,
))
# We can not out put this as `tablib.Dataset(*row).csv` as the
# documentation recommends, as each row has a different length, and
# tablib throws an error because of this. Outputting each row one by
# results in the same output, without a giant load of extra columns on
# some rows
for row in data:
yield tablib.Dataset(row).csv