fix: track vendor name/SKU per OrderItem

and include vendor name filter by default for Placement, Receiving views
This commit is contained in:
Lance Edgar 2025-02-20 08:59:00 -06:00
parent 7ea83b2715
commit d8b37969c5
7 changed files with 117 additions and 0 deletions

View file

@ -938,6 +938,8 @@ class NewOrderBatchHandler(BatchHandler):
row.department_id = product.department_id row.department_id = product.department_id
row.department_name = product.department_name row.department_name = product.department_name
row.special_order = product.special_order row.special_order = product.special_order
row.vendor_name = product.vendor_name
row.vendor_item_code = product.vendor_item_code
row.case_size = product.case_size row.case_size = product.case_size
row.unit_cost = product.unit_cost row.unit_cost = product.unit_cost
row.unit_price_reg = product.unit_price_reg row.unit_price_reg = product.unit_price_reg
@ -959,6 +961,8 @@ class NewOrderBatchHandler(BatchHandler):
row.department_id = product.department_id row.department_id = product.department_id
row.department_name = product.department_name row.department_name = product.department_name
row.special_order = product.special_order row.special_order = product.special_order
row.vendor_name = product.vendor_name
row.vendor_item_code = product.vendor_item_code
row.case_size = product.case_size row.case_size = product.case_size
row.unit_cost = product.unit_cost row.unit_cost = product.unit_cost
row.unit_price_reg = product.unit_price_reg row.unit_price_reg = product.unit_price_reg
@ -1196,6 +1200,8 @@ class NewOrderBatchHandler(BatchHandler):
'product_weighed', 'product_weighed',
'department_id', 'department_id',
'department_name', 'department_name',
'vendor_name',
'vendor_item_code',
'case_size', 'case_size',
'order_qty', 'order_qty',
'order_uom', 'order_uom',

View file

@ -0,0 +1,41 @@
"""add order_item.vendor*
Revision ID: 13af2ffbc0e0
Revises: a4273360d379
Create Date: 2025-02-19 19:36:30.308840
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
import wuttjamaican.db.util
# revision identifiers, used by Alembic.
revision: str = '13af2ffbc0e0'
down_revision: Union[str, None] = 'a4273360d379'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# sideshow_batch_neworder_row
op.add_column('sideshow_batch_neworder_row', sa.Column('vendor_name', sa.String(length=50), nullable=True))
op.add_column('sideshow_batch_neworder_row', sa.Column('vendor_item_code', sa.String(length=20), nullable=True))
# sideshow_order_item
op.add_column('sideshow_order_item', sa.Column('vendor_name', sa.String(length=50), nullable=True))
op.add_column('sideshow_order_item', sa.Column('vendor_item_code', sa.String(length=20), nullable=True))
def downgrade() -> None:
# sideshow_order_item
op.drop_column('sideshow_order_item', 'vendor_item_code')
op.drop_column('sideshow_order_item', 'vendor_name')
# sideshow_batch_neworder_row
op.drop_column('sideshow_batch_neworder_row', 'vendor_item_code')
op.drop_column('sideshow_batch_neworder_row', 'vendor_name')

View file

@ -252,6 +252,16 @@ class NewOrderBatchRow(model.BatchRowMixin, model.Base):
normally carried by the store. Default is null. normally carried by the store. Default is null.
""") """)
vendor_name = sa.Column(sa.String(length=50), nullable=True, doc="""
Name of vendor from which product may be purchased, if known. See
also :attr:`vendor_item_code`.
""")
vendor_item_code = sa.Column(sa.String(length=20), nullable=True, doc="""
Item code (SKU) to use when ordering this product from the vendor
identified by :attr:`vendor_name`, if known.
""")
case_size = sa.Column(sa.Numeric(precision=10, scale=4), nullable=True, doc=""" case_size = sa.Column(sa.Numeric(precision=10, scale=4), nullable=True, doc="""
Case pack count for the product, if known. Case pack count for the product, if known.

View file

@ -253,6 +253,16 @@ class OrderItem(model.Base):
normally carried by the store. Default is null. normally carried by the store. Default is null.
""") """)
vendor_name = sa.Column(sa.String(length=50), nullable=True, doc="""
Name of vendor from which product may be purchased, if known. See
also :attr:`vendor_item_code`.
""")
vendor_item_code = sa.Column(sa.String(length=20), nullable=True, doc="""
Item code (SKU) to use when ordering this product from the vendor
identified by :attr:`vendor_name`, if known.
""")
case_size = sa.Column(sa.Numeric(precision=10, scale=4), nullable=True, doc=""" case_size = sa.Column(sa.Numeric(precision=10, scale=4), nullable=True, doc="""
Case pack count for the product, if known. Case pack count for the product, if known.
""") """)

View file

@ -243,6 +243,12 @@
<b-field horizontal label="Special Order"> <b-field horizontal label="Special Order">
<span>${app.render_boolean(item.special_order)}</span> <span>${app.render_boolean(item.special_order)}</span>
</b-field> </b-field>
<b-field horizontal label="Vendor Name">
<span>${item.vendor_name}</span>
</b-field>
<b-field horizontal label="Vendor Item Code">
<span>${item.vendor_item_code}</span>
</b-field>
</div> </div>
</div> </div>
</nav> </nav>

View file

@ -1562,6 +1562,26 @@ class PlacementView(OrderItemView):
route_prefix = 'order_items_placement' route_prefix = 'order_items_placement'
url_prefix = '/placement' url_prefix = '/placement'
grid_columns = [
'order_id',
'store_id',
'customer_name',
'product_brand',
'product_description',
'product_size',
'department_name',
'special_order',
'vendor_name',
'vendor_item_code',
'order_qty',
'order_uom',
'total_price',
]
filter_defaults = {
'vendor_name': {'active': True},
}
def get_query(self, session=None): def get_query(self, session=None):
""" """ """ """
query = super().get_query(session=session) query = super().get_query(session=session)
@ -1664,6 +1684,26 @@ class ReceivingView(OrderItemView):
route_prefix = 'order_items_receiving' route_prefix = 'order_items_receiving'
url_prefix = '/receiving' url_prefix = '/receiving'
grid_columns = [
'order_id',
'store_id',
'customer_name',
'product_brand',
'product_description',
'product_size',
'department_name',
'special_order',
'vendor_name',
'vendor_item_code',
'order_qty',
'order_uom',
'total_price',
]
filter_defaults = {
'vendor_name': {'active': True},
}
def get_query(self, session=None): def get_query(self, session=None):
""" """ """ """
query = super().get_query(session=session) query = super().get_query(session=session)

View file

@ -818,6 +818,8 @@ class TestNewOrderBatchHandler(DataTestCase):
brand_name='Bragg', brand_name='Bragg',
description='Vinegar', description='Vinegar',
size='32oz', size='32oz',
vendor_name='Acme Distributors',
vendor_item_code='1234',
created_by=user, created_by=user,
status=enum.PendingProductStatus.PENDING) status=enum.PendingProductStatus.PENDING)
row = handler.make_row(pending_product=product, order_qty=1, order_uom=enum.ORDER_UOM_UNIT) row = handler.make_row(pending_product=product, order_qty=1, order_uom=enum.ORDER_UOM_UNIT)
@ -830,6 +832,8 @@ class TestNewOrderBatchHandler(DataTestCase):
self.assertEqual(row.product_brand, 'Bragg') self.assertEqual(row.product_brand, 'Bragg')
self.assertEqual(row.product_description, 'Vinegar') self.assertEqual(row.product_description, 'Vinegar')
self.assertEqual(row.product_size, '32oz') self.assertEqual(row.product_size, '32oz')
self.assertEqual(row.vendor_name, 'Acme Distributors')
self.assertEqual(row.vendor_item_code, '1234')
self.assertIsNone(row.case_size) self.assertIsNone(row.case_size)
self.assertIsNone(row.unit_cost) self.assertIsNone(row.unit_cost)
self.assertIsNone(row.unit_price_reg) self.assertIsNone(row.unit_price_reg)