Add basic support for vendor catalog batch feature
This commit is contained in:
		
							parent
							
								
									b8ce21b6c0
								
							
						
					
					
						commit
						1177ca6591
					
				
					 9 changed files with 301 additions and 16 deletions
				
			
		
							
								
								
									
										0
									
								
								corporal/batch/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								corporal/batch/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										208
									
								
								corporal/batch/vendorcatalog.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								corporal/batch/vendorcatalog.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,208 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8; -*-
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Handler for Vendor Catalog batches
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import decimal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from sqlalchemy import orm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from corepos.db.office_op import Session as CoreSession, model as corepos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from rattail_corepos.corepos.api import make_corepos_api
 | 
				
			||||||
 | 
					from rattail_corepos.batch import vendorcatalog as base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VendorCatalogHandler(base.VendorCatalogHandler):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Handler for vendor catalog batches.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    # upstream logic requires versioning hacks, but we do not
 | 
				
			||||||
 | 
					    populate_with_versioning = True
 | 
				
			||||||
 | 
					    refresh_with_versioning = True
 | 
				
			||||||
 | 
					    execute_with_versioning = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # catalog parsers will favor case cost, but CORE favors unit cost.  so we
 | 
				
			||||||
 | 
					    # always "ignore" unit cost diffs less than one penny to avoid useless
 | 
				
			||||||
 | 
					    # updates caused by simple rounding
 | 
				
			||||||
 | 
					    unit_cost_diff_threshold = decimal.Decimal('0.01')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setup_common(self, batch, progress=None):
 | 
				
			||||||
 | 
					        self.core_session = CoreSession()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        query = self.core_session.query(corepos.Product)\
 | 
				
			||||||
 | 
					                                 .options(orm.joinedload(corepos.Product.vendor_items))
 | 
				
			||||||
 | 
					        self.core_products_by_upc = self.cache_model(self.core_session,
 | 
				
			||||||
 | 
					                                                     corepos.Product,
 | 
				
			||||||
 | 
					                                                     key='upc',
 | 
				
			||||||
 | 
					                                                     query=query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        query = self.core_session.query(corepos.VendorItem)\
 | 
				
			||||||
 | 
					                                 .filter(corepos.VendorItem.vendor_id == int(batch.vendor_id))
 | 
				
			||||||
 | 
					        self.core_vendor_items_by_sku = self.cache_model(self.core_session,
 | 
				
			||||||
 | 
					                                                         corepos.VendorItem,
 | 
				
			||||||
 | 
					                                                         key='sku',
 | 
				
			||||||
 | 
					                                                         query=query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setup_populate = setup_common
 | 
				
			||||||
 | 
					    setup_refresh = setup_common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def teardown_common(self, batch, progress=None):
 | 
				
			||||||
 | 
					        self.core_session.rollback()
 | 
				
			||||||
 | 
					        self.core_session.close()
 | 
				
			||||||
 | 
					        del self.core_session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    teardown_populate = teardown_common
 | 
				
			||||||
 | 
					    teardown_refresh = teardown_common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_row(self, batch, row):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # parser logic sets upc but we want to use item_id
 | 
				
			||||||
 | 
					        row.item_id = str(row.upc)[:-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # okay now continue as normal
 | 
				
			||||||
 | 
					        # (note, this must come last b/c it will refresh row)
 | 
				
			||||||
 | 
					        super(VendorCatalogHandler, self).add_row(batch, row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def refresh_row(self, row):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # clear this first in case it's set
 | 
				
			||||||
 | 
					        row.status_text = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # find the CORE `products` record, matching by `products.upc`
 | 
				
			||||||
 | 
					        core_product = self.core_products_by_upc.get(row.item_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # find the CORE `vendorItems` record, matching by `vendorItems.sku`
 | 
				
			||||||
 | 
					        core_vendor_item = self.core_vendor_items_by_sku.get(row.vendor_code)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # if the catalog UPC is not found in `products` but the SKU *is* found
 | 
				
			||||||
 | 
					        # in `vendorItems` *and* the latter ties back to valid `products`
 | 
				
			||||||
 | 
					        # record, then we want to pretend that matched all along.  and not just
 | 
				
			||||||
 | 
					        # for the moment, but going forward; so we also update `row.item_id`
 | 
				
			||||||
 | 
					        if not core_product and core_vendor_item:
 | 
				
			||||||
 | 
					            core_product = core_vendor_item.product
 | 
				
			||||||
 | 
					            if core_product:
 | 
				
			||||||
 | 
					                row.item_id = core_product.upc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # figure out if this vendor is already default for the product.  if the
 | 
				
			||||||
 | 
					        # product does not yet have a default, let this vendor be it.
 | 
				
			||||||
 | 
					        row.is_preferred_vendor = False
 | 
				
			||||||
 | 
					        row.make_preferred_vendor = False
 | 
				
			||||||
 | 
					        if core_product:
 | 
				
			||||||
 | 
					            if core_product.default_vendor_id and (
 | 
				
			||||||
 | 
					                    str(core_product.default_vendor_id) == row.batch.vendor_id):
 | 
				
			||||||
 | 
					                row.is_preferred_vendor = True
 | 
				
			||||||
 | 
					            if not core_product.default_vendor_id:
 | 
				
			||||||
 | 
					                row.make_preferred_vendor = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # declare "product not found" if we did not find any matches in CORE
 | 
				
			||||||
 | 
					        if not core_vendor_item and not core_product:
 | 
				
			||||||
 | 
					            row.status_code = row.STATUS_PRODUCT_NOT_FOUND
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # declare "new cost" if we found `products` match but not `vendorItems`
 | 
				
			||||||
 | 
					        if not core_vendor_item:
 | 
				
			||||||
 | 
					            row.status_code = row.STATUS_NEW_COST
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # declare "change product" if `vendorItems.upc` != `products.upc`
 | 
				
			||||||
 | 
					        if core_vendor_item.upc != row.item_id:
 | 
				
			||||||
 | 
					            row.status_code = row.STATUS_CHANGE_PRODUCT
 | 
				
			||||||
 | 
					            row.status_text = "new UPC {} differs from old UPC {}".format(
 | 
				
			||||||
 | 
					                row.item_id, core_vendor_item.upc)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # declare "old" `vendorItems` data
 | 
				
			||||||
 | 
					        row.old_vendor_code = core_vendor_item.sku
 | 
				
			||||||
 | 
					        row.old_case_size = core_vendor_item.units
 | 
				
			||||||
 | 
					        row.old_unit_cost = core_vendor_item.cost
 | 
				
			||||||
 | 
					        row.old_case_cost = (core_vendor_item.cost * decimal.Decimal(core_vendor_item.units))\
 | 
				
			||||||
 | 
					           .quantize(decimal.Decimal('0.12345'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.refresh_cost_diffs(row)
 | 
				
			||||||
 | 
					        self.set_status_per_diffs(row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def describe_execution(self, batch, **kwargs):
 | 
				
			||||||
 | 
					        return ("The `vendorItems` table in CORE-POS will be updated directly "
 | 
				
			||||||
 | 
					                "via API, for all rows indicating a change etc.  In some cases "
 | 
				
			||||||
 | 
					                "`products` may also be updated as appropriate.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def execute(self, batch, progress=None, **kwargs):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Update CORE-POS etc.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        rows = [row for row in batch.active_rows()
 | 
				
			||||||
 | 
					                if row.status_code in (row.STATUS_NEW_COST,
 | 
				
			||||||
 | 
					                                       # row.STATUS_UPDATE_COST,
 | 
				
			||||||
 | 
					                                       # row.STATUS_CHANGE_VENDOR_ITEM_CODE,
 | 
				
			||||||
 | 
					                                       row.STATUS_CHANGE_CASE_SIZE,
 | 
				
			||||||
 | 
					                                       row.STATUS_CHANGE_COST,
 | 
				
			||||||
 | 
					                                       row.STATUS_CHANGE_PRODUCT)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if rows:
 | 
				
			||||||
 | 
					            self.api = make_corepos_api(self.config)
 | 
				
			||||||
 | 
					            self.update_corepos(batch, rows, batch.vendor_id, progress=progress,
 | 
				
			||||||
 | 
					                                # update_product_costs=kwargs.get('update_product_costs', False),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update_corepos(self, batch, rows, vendor_id, progress=None,
 | 
				
			||||||
 | 
					                       # TODO: this kwarg seems perhaps useful, but for now we
 | 
				
			||||||
 | 
					                       # are auto-detecting when such an update is needed
 | 
				
			||||||
 | 
					                       #update_product_costs=False,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Update the `vendorItems` table in CORE-POS (and maybe `products` too).
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def update(row, i):
 | 
				
			||||||
 | 
					            # we may need this value in a couple places
 | 
				
			||||||
 | 
					            unit_cost = float(row.unit_cost)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # figure out if we are "updating the same, primary" cost record,
 | 
				
			||||||
 | 
					            # b/c if so we will want to update product accordingly also.  this
 | 
				
			||||||
 | 
					            # is always the case when this is the first vendor for product.
 | 
				
			||||||
 | 
					            # updating_primary = first_vendor
 | 
				
			||||||
 | 
					            updating_primary = row.make_preferred_vendor
 | 
				
			||||||
 | 
					            if not updating_primary:
 | 
				
			||||||
 | 
					                core_vendor_items = self.api.get_vendor_items(upc=row.item_id)
 | 
				
			||||||
 | 
					                if core_vendor_items:
 | 
				
			||||||
 | 
					                    core_vendor_item = core_vendor_items[0]
 | 
				
			||||||
 | 
					                    if core_vendor_item['sku'] == row.vendor_code:
 | 
				
			||||||
 | 
					                        updating_primary = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # create or update the `vendorItems` record in CORE
 | 
				
			||||||
 | 
					            self.api.set_vendor_item(sku=row.vendor_code,
 | 
				
			||||||
 | 
					                                     vendorID=vendor_id,
 | 
				
			||||||
 | 
					                                     upc=row.item_id,
 | 
				
			||||||
 | 
					                                     brand=row.brand_name,
 | 
				
			||||||
 | 
					                                     description=row.description,
 | 
				
			||||||
 | 
					                                     size=row.size,
 | 
				
			||||||
 | 
					                                     units=row.case_size,
 | 
				
			||||||
 | 
					                                     cost=unit_cost,
 | 
				
			||||||
 | 
					                                     # TODO: we (may) have vendor SRP, but pretty
 | 
				
			||||||
 | 
					                                     # sure CORE has different plans for its `srp`
 | 
				
			||||||
 | 
					                                     #srp=row.suggested_retail,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # TODO: CORE does not have the concept of a true "default"
 | 
				
			||||||
 | 
					            # `vendorItems` record, but rather uses the `modified` timestamp
 | 
				
			||||||
 | 
					            # for pseudo-default.  this means any given product may wind up
 | 
				
			||||||
 | 
					            # with a new/different pseudo-default when the above operation
 | 
				
			||||||
 | 
					            # completes.  in which case, perhaps we should *always* update
 | 
				
			||||||
 | 
					            # `products.cost` accordingly (below)..?  er, still only if the
 | 
				
			||||||
 | 
					            # product's `default_vendor_id` matches at least, i guess...  for
 | 
				
			||||||
 | 
					            # now we are only doing so if it "obviously" needs it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # maybe also update `products` record in CORE
 | 
				
			||||||
 | 
					            kwargs = {}
 | 
				
			||||||
 | 
					            if updating_primary:
 | 
				
			||||||
 | 
					                kwargs['cost'] = unit_cost
 | 
				
			||||||
 | 
					            if row.make_preferred_vendor:
 | 
				
			||||||
 | 
					                kwargs['default_vendor_id'] = vendor_id
 | 
				
			||||||
 | 
					            if kwargs:
 | 
				
			||||||
 | 
					                self.api.set_product(upc=row.item_id, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.progress_loop(update, rows, progress,
 | 
				
			||||||
 | 
					                           message="Updating CORE-POS via API")
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,11 @@ class CorporalConfig(ConfigExtension):
 | 
				
			||||||
    def configure(self, config):
 | 
					    def configure(self, config):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # set some default config values
 | 
					        # set some default config values
 | 
				
			||||||
 | 
					        config.setdefault('rattail', 'model', 'corporal.db.model')
 | 
				
			||||||
        config.setdefault('rattail.mail', 'emails', 'corporal.emails')
 | 
					        config.setdefault('rattail.mail', 'emails', 'corporal.emails')
 | 
				
			||||||
        config.setdefault('rattail', 'settings', 'corporal.settings')
 | 
					        config.setdefault('rattail', 'settings', 'corporal.settings')
 | 
				
			||||||
        config.setdefault('tailbone', 'menus', 'corporal.web.menus')
 | 
					        config.setdefault('tailbone', 'menus', 'corporal.web.menus')
 | 
				
			||||||
        config.setdefault('rattail.config', 'templates', 'corporal:data/config rattail:data/config')
 | 
					        config.setdefault('rattail.config', 'templates', 'corporal:data/config rattail:data/config')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # batches
 | 
				
			||||||
 | 
					        config.setdefault('rattail.batch', 'vendor_catalog.handler', 'corporal.batch.vendorcatalog:VendorCatalogHandler')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								corporal/db/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								corporal/db/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										10
									
								
								corporal/db/model.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								corporal/db/model.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8; -*-
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Corporal data model w/ CORE-POS integration
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# bring in all the normal stuff from Rattail
 | 
				
			||||||
 | 
					from rattail.db.model import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# also bring in CORE integration models
 | 
				
			||||||
 | 
					from rattail_corepos.db.model import *
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,18 @@ def simple_menus(request):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    corepos_menu = make_corepos_menu(request)
 | 
					    corepos_menu = make_corepos_menu(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    batch_menu = {
 | 
				
			||||||
 | 
					        'title': "Batches",
 | 
				
			||||||
 | 
					        'type': 'menu',
 | 
				
			||||||
 | 
					        'items': [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'title': "Vendor Catalogs",
 | 
				
			||||||
 | 
					                'url': url('vendorcatalogs'),
 | 
				
			||||||
 | 
					                'perm': 'vendorcatalogs.list',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    admin_menu = {
 | 
					    admin_menu = {
 | 
				
			||||||
        'title': "Admin",
 | 
					        'title': "Admin",
 | 
				
			||||||
        'type': 'menu',
 | 
					        'type': 'menu',
 | 
				
			||||||
| 
						 | 
					@ -67,6 +79,7 @@ def simple_menus(request):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    menus = [
 | 
					    menus = [
 | 
				
			||||||
        corepos_menu,
 | 
					        corepos_menu,
 | 
				
			||||||
 | 
					        batch_menu,
 | 
				
			||||||
        admin_menu,
 | 
					        admin_menu,
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,27 +14,14 @@ def includeme(config):
 | 
				
			||||||
    config.include('tailbone.views.progress')
 | 
					    config.include('tailbone.views.progress')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # main table views
 | 
					    # main table views
 | 
				
			||||||
    config.include('tailbone.views.customergroups')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.datasync')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.email')
 | 
					    config.include('tailbone.views.email')
 | 
				
			||||||
    config.include('tailbone.views.families')
 | 
					 | 
				
			||||||
    config.include('tailbone_corepos.views.members')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.messages')
 | 
					 | 
				
			||||||
    config.include('tailbone_corepos.views.people')
 | 
					    config.include('tailbone_corepos.views.people')
 | 
				
			||||||
    config.include('tailbone.views.reportcodes')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.roles')
 | 
					    config.include('tailbone.views.roles')
 | 
				
			||||||
    config.include('tailbone.views.settings')
 | 
					    config.include('tailbone.views.settings')
 | 
				
			||||||
    config.include('tailbone_corepos.views.subdepartments')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.shifts')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.users')
 | 
					    config.include('tailbone.views.users')
 | 
				
			||||||
    config.include('tailbone.views.stores')
 | 
					 | 
				
			||||||
    config.include('tailbone_corepos.views.customers')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.employees')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.taxes')
 | 
					 | 
				
			||||||
    config.include('tailbone_corepos.views.departments')
 | 
					 | 
				
			||||||
    config.include('tailbone.views.brands')
 | 
					 | 
				
			||||||
    config.include('tailbone_corepos.views.vendors')
 | 
					 | 
				
			||||||
    config.include('tailbone_corepos.views.products')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # CORE-POS direct data views
 | 
					    # CORE-POS direct data views
 | 
				
			||||||
    config.include('tailbone_corepos.views.corepos')
 | 
					    config.include('tailbone_corepos.views.corepos')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # batches
 | 
				
			||||||
 | 
					    config.include('corporal.web.views.batch.vendorcatalog')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								corporal/web/views/batch/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								corporal/web/views/batch/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										63
									
								
								corporal/web/views/batch/vendorcatalog.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								corporal/web/views/batch/vendorcatalog.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8; -*-
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Vendor Catalog Batch views for Corporal
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from corepos.db.office_op import model as corepos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from deform import widget as dfwidget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tailbone.views.batch import vendorcatalog as base
 | 
				
			||||||
 | 
					from tailbone_corepos.db import CoreOfficeSession
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VendorCatalogView(base.VendorCatalogView):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Master view for vendor catalog batches.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    form_fields = [
 | 
				
			||||||
 | 
					        'id',
 | 
				
			||||||
 | 
					        'description',
 | 
				
			||||||
 | 
					        'vendor_id',
 | 
				
			||||||
 | 
					        'vendor_name',
 | 
				
			||||||
 | 
					        'filename',
 | 
				
			||||||
 | 
					        'notes',
 | 
				
			||||||
 | 
					        'created',
 | 
				
			||||||
 | 
					        'created_by',
 | 
				
			||||||
 | 
					        'rowcount',
 | 
				
			||||||
 | 
					        'executed',
 | 
				
			||||||
 | 
					        'executed_by',
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def configure_form(self, f):
 | 
				
			||||||
 | 
					        super(VendorCatalogView, self).configure_form(f)
 | 
				
			||||||
 | 
					        model = self.model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # vendor_id
 | 
				
			||||||
 | 
					        if self.creating:
 | 
				
			||||||
 | 
					            vendors = CoreOfficeSession.query(corepos.Vendor)\
 | 
				
			||||||
 | 
					                                       .order_by(corepos.Vendor.name)\
 | 
				
			||||||
 | 
					                                       .all()
 | 
				
			||||||
 | 
					            values = [(str(vendor.id), vendor.name)
 | 
				
			||||||
 | 
					                      for vendor in vendors]
 | 
				
			||||||
 | 
					            f.set_widget('vendor_id', dfwidget.SelectWidget(values=values))
 | 
				
			||||||
 | 
					            f.set_required('vendor_id')
 | 
				
			||||||
 | 
					            f.set_label('vendor_id', "Vendor")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # vendor_name
 | 
				
			||||||
 | 
					        if self.creating:
 | 
				
			||||||
 | 
					            f.remove('vendor_name')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_batch_kwargs(self, batch):
 | 
				
			||||||
 | 
					        kwargs = super(VendorCatalogView, self).get_batch_kwargs(batch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if 'vendor_name' not in kwargs and batch.vendor_id:
 | 
				
			||||||
 | 
					            vendor = CoreOfficeSession.query(corepos.Vendor).get(batch.vendor_id)
 | 
				
			||||||
 | 
					            if vendor:
 | 
				
			||||||
 | 
					                kwargs['vendor_name'] = vendor.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def includeme(config):
 | 
				
			||||||
 | 
					    VendorCatalogView.defaults(config)
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue