Add support for making new label batch from CSV file

This commit is contained in:
Lance Edgar 2016-11-07 15:04:41 -06:00
parent 2725f55e4a
commit 1e69fb260c

View file

@ -26,13 +26,21 @@ Handler for label batches
from __future__ import unicode_literals, absolute_import
import csv
import logging
import sqlalchemy as sa
from rattail import enum
from rattail.db import model, api
from rattail.gpc import GPC
from rattail.db.batch.handler import BatchHandler
from rattail.util import progress_loop
from rattail.time import make_utc
from rattail.config import parse_bool
log = logging.getLogger(__name__)
class LabelBatchHandler(BatchHandler):
@ -43,30 +51,72 @@ class LabelBatchHandler(BatchHandler):
model_title = "Label Batch"
show_progress = True
def make_batch(self, session, products=None, progress=None, **kwargs):
def make_batch(self, session, filepath=None, products=None, progress=None, **kwargs):
"""
Create a new label batch and maybe fill it, if we were given something
good to work with. A HandheldBatch or sequence/query of Product
objects are supported for source data.
"""
batch = model.LabelBatch(**kwargs)
if products:
self.label_profile = self.get_label_profile(session)
assert self.label_profile
self.now = make_utc()
self.setup()
self.sequence = 1
if filepath:
kwargs['progress'] = progress
batch = self.make_batch_from_file(session, filepath, **kwargs)
elif products:
batch = model.LabelBatch(**kwargs)
self.rebuild_from_products(session, batch, products, progress)
self.teardown()
return batch
def make_batch_from_file(self, session, path, skip_first_line=False,
calc_check_digit='upc', progress=None, **kwargs):
"""
Make a new batch using the given file as data source.
"""
skip_first_line = parse_bool(skip_first_line)
if calc_check_digit != 'upc':
calc_check_digit = parse_bool(calc_check_digit)
batch = model.LabelBatch(**kwargs)
with open(path, 'rb') as f:
if skip_first_line:
f.readline()
reader = csv.reader(f)
lines = list(reader)
def convert(line, i):
upc = line[0].strip()
if not upc:
return
upc = GPC(upc, calc_check_digit=calc_check_digit)
product = api.get_product_by_upc(session, upc)
if not product:
log.warning("product not found: {}".format(upc))
return
row = model.LabelBatchRow(sequence=self.sequence)
self.sequence += 1
row.product = product
row.label_code = self.label_profile.code
row.label_profile = self.label_profile
row.label_quantity = 1
batch.data_rows.append(row)
self.cognize_row(session, row)
progress_loop(convert, lines, progress,
message="Adding batch rows from file")
return batch
def rebuild_from_products(self, session, batch, products, progress=None):
"""
Rebuild the given batch from the given products.
"""
self.label_profile = self.get_label_profile(session)
assert self.label_profile
self.setup()
del batch.data_rows[:]
self.sequence = 1
self.now = make_utc()
def convert(product, i):
row = model.LabelBatchRow(sequence=self.sequence)
self.sequence += 1
@ -80,8 +130,6 @@ class LabelBatchHandler(BatchHandler):
progress_loop(convert, products, progress, count=products.count(),
message="Copying product rows to label batch")
self.teardown()
def refresh_data(self, session, batch, progress=None):
"""
Refresh all data for the batch.
@ -156,7 +204,9 @@ class LabelBatchHandler(BatchHandler):
row.pack_price = regular_price.pack_price if regular_price else None
sale_price = product.current_price
if sale_price:
if sale_price.type == enum.PRICE_TYPE_SALE and sale_price.starts <= self.now <= sale_price.ends:
if (sale_price.type == enum.PRICE_TYPE_SALE and
sale_price.starts and sale_price.starts <= self.now and
sale_price.ends and sale_price.ends >= self.now):
pass # this is what we want
else:
sale_price = None
@ -187,6 +237,8 @@ class LabelBatchHandler(BatchHandler):
profiles = {}
def organize(row, i):
if row.removed:
return
profile = row.label_profile
if profile.uuid not in profiles:
profiles[profile.uuid] = profile