Files
@ 180c9314d848
Branch filter:
Location: rattail-project/rattail/rattail/contrib/vendors/invoices/unfi.py
180c9314d848
4.2 KiB
text/x-python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | # -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Vendor invoice parser for United Natural Foods (UNFI)
"""
from __future__ import unicode_literals, absolute_import
import datetime
from rattail.db import model
from rattail.gpc import GPC
from rattail.vendors.invoices import InvoiceParser
from rattail.csvutil import UnicodeDictReader, UnicodeReader
class UnfiInvoiceParser(InvoiceParser):
"""
Parser for UNFI CSV invoice files.
"""
key = 'rattail.contrib.unfi'
display = "United Natural Foods (UNFI)"
vendor_key = 'unfi'
def parse_invoice_date(self, data_path):
with open(data_path, 'rb') as f:
reader = UnicodeDictReader(f, encoding='latin_1')
data = reader.next()
return datetime.datetime.strptime(data['InvoiceDate'], '%m/%d/%Y').date()
def parse_rows(self, data_path):
with open(data_path, 'rb') as csv_file:
# TODO: The following logic is largely copied from the Scan Genius
# order parser (in `rattail_livnat.scangenius`). I wonder if we
# can abstract it into a generic yet custom CSV parser...?
# We want to ignore the header section here. However the use of
# UnicodeDictReader below requires iteration, and yet also expects
# the "beginning" of the file to contain the fieldnames. To force
# this all to play nicely, we calculate our offset and then seek to
# it explicitly. It's probably likely that there is a better way,
# but this works.
offset = self.find_details_offset(csv_file)
csv_file.seek(offset)
reader = UnicodeDictReader(csv_file, encoding='latin_1')
for data in reader:
# Only consider 'Detail' rows; this check is mostly for the
# sake of ignoring 'Footer' rows.
if data['RecType'] != 'Detail':
continue
row = model.VendorInvoiceRow()
row.upc = GPC(data['UPC'].replace('-', ''))
row.vendor_code = data['ProductID']
row.brand_name = data['Brand']
row.description = data['Description']
row.size = data['Size']
row.case_quantity = self.int_(data['Servings'])
row.ordered_cases = int(self.decimal(data['QuantityOrdered']))
row.shipped_cases = self.int_(data['QuantityShipped'])
row.unit_cost = self.decimal(data['NetPricePerUnit'])
row.total_cost = self.decimal(data['ExtendedPrice'])
row.case_cost = row.unit_cost * row.case_quantity
yield row
def find_details_offset(self, csv_file):
"""
Find the character offset of the details data within a CSV file.
"""
# TODO: The following logic is largely copied from the Scan Genius
# order parser (in ``rattail_livnat.scangenius``). I wonder if we can
# abstract it into a generic yet custom CSV parser...?
# Calculate the offset of the details section, based on the sum
# character length of the header section (which is 2 lines long).
reader = UnicodeReader(csv_file, encoding='latin_1')
offset = 0
for line, row in enumerate(csv_file, 1):
offset += len(row)
if line == 2:
break
return offset
|