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 from __future__ import unicode_literals, absolute_import
import csv
import logging
import sqlalchemy as sa import sqlalchemy as sa
from rattail import enum from rattail import enum
from rattail.db import model, api from rattail.db import model, api
from rattail.gpc import GPC
from rattail.db.batch.handler import BatchHandler from rattail.db.batch.handler import BatchHandler
from rattail.util import progress_loop from rattail.util import progress_loop
from rattail.time import make_utc from rattail.time import make_utc
from rattail.config import parse_bool
log = logging.getLogger(__name__)
class LabelBatchHandler(BatchHandler): class LabelBatchHandler(BatchHandler):
@ -43,30 +51,72 @@ class LabelBatchHandler(BatchHandler):
model_title = "Label Batch" model_title = "Label Batch"
show_progress = True 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 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 good to work with. A HandheldBatch or sequence/query of Product
objects are supported for source data. objects are supported for source data.
""" """
batch = model.LabelBatch(**kwargs) self.label_profile = self.get_label_profile(session)
if products: 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.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 return batch
def rebuild_from_products(self, session, batch, products, progress=None): def rebuild_from_products(self, session, batch, products, progress=None):
""" """
Rebuild the given batch from the given products. 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): def convert(product, i):
row = model.LabelBatchRow(sequence=self.sequence) row = model.LabelBatchRow(sequence=self.sequence)
self.sequence += 1 self.sequence += 1
@ -80,8 +130,6 @@ class LabelBatchHandler(BatchHandler):
progress_loop(convert, products, progress, count=products.count(), progress_loop(convert, products, progress, count=products.count(),
message="Copying product rows to label batch") message="Copying product rows to label batch")
self.teardown()
def refresh_data(self, session, batch, progress=None): def refresh_data(self, session, batch, progress=None):
""" """
Refresh all data for the batch. 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 row.pack_price = regular_price.pack_price if regular_price else None
sale_price = product.current_price sale_price = product.current_price
if sale_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 pass # this is what we want
else: else:
sale_price = None sale_price = None
@ -187,6 +237,8 @@ class LabelBatchHandler(BatchHandler):
profiles = {} profiles = {}
def organize(row, i): def organize(row, i):
if row.removed:
return
profile = row.label_profile profile = row.label_profile
if profile.uuid not in profiles: if profile.uuid not in profiles:
profiles[profile.uuid] = profile profiles[profile.uuid] = profile