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