Add support for making new label batch from CSV file
This commit is contained in:
		
							parent
							
								
									2725f55e4a
								
							
						
					
					
						commit
						1e69fb260c
					
				
					 1 changed files with 67 additions and 15 deletions
				
			
		|  | @ -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. | ||||||
|         """ |         """ | ||||||
|  |         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) |             batch = model.LabelBatch(**kwargs) | ||||||
|         if products: |  | ||||||
|             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 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar