From 579f6dde4bfe8f0d57a31b7d5d7deb9dc76d37a9 2023-10-13 08:56:37 From: Ben Sturmfels Date: 2023-10-13 08:56:37 Subject: [PATCH] Add importer for Printful Orders.csv file --- diff --git a/import2ledger/importers/printful.py b/import2ledger/importers/printful.py new file mode 100644 index 0000000000000000000000000000000000000000..0f984e1d73f27660835f896b521b68fead33914b --- /dev/null +++ b/import2ledger/importers/printful.py @@ -0,0 +1,58 @@ +import re + +from . import _csv +from .. import strparse + + +class SalesImporter(_csv.CSVImporterBase): + DECIMAL_FIELDS = { + 'Products': 'products', + 'Shipping': 'shipping_fees', + 'Tax': 'tax', + 'VAT': 'vat', + 'Total': 'amount', + 'Discount': 'discount', + } + NEEDED_FIELDS = {'Printful ID', *DECIMAL_FIELDS} + COPIED_FIELDS = {} + CURRENCY_MAP = { + '$': 'USD', + '€': 'EUR', + '£': 'GBP', + 'AU$': 'AUD', + 'C$': 'CAD', + } + currency_regexp = re.compile(r'-?(?P\D*)\d.*') + + def __init__(self, input_file): + # Orders.csv file is in UTF-8-SIG encoding and begins with a byte order + # mark character \ufeff. This happens *after* NEEDED_FIELDS is + # checked. This encoding check is done conditionally to handle the + # situation where someone has modified the CSV and saved as UTF-8. + first_char = input_file.read(1) + input_file.seek(0) + if first_char == '\ufeff': + input_file.reconfigure(encoding='UTF-8-SIG') + super().__init__(input_file) + + def _read_row(self, row): + if row['Date'].startswith('Total paid'): + return None + + # Parse the currency values. A hyphen represents zero. + record = { + self.DECIMAL_FIELDS[key]: strparse.currency_decimal(row[key] if row[key] != '-' else '0') + for key in self.DECIMAL_FIELDS + } + + # Most importers don't deal with multiple currencies. There are + # libraries that partly help with currency codes and symbols, but the + # codes/symbols Printful use have some quirks, so it's easier to do this + # ourselves. + currency_code = re.match(self.currency_regexp, row['Total']).group('currency') + record['currency'] = self.CURRENCY_MAP.get(currency_code, currency_code).replace('$', '') + + record['date'] = strparse.date(row['Date'], '%B %d, %Y') + record['order_id'] = row['Order'].lstrip('Order ') + record['payee'] = 'Printful' # Not used but required to be set + return record