diff --git a/src/db/index.ts b/src/db/index.ts index 5a78de7..db94e19 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -202,6 +202,38 @@ export class StockFillDB extends Dexie { }), ); }); + + this.version(7) + .stores({ + products: 'id, name, category, &barcode, archived, created_at, updated_at', + areas: 'id, name, created_at, updated_at', + pickLists: + 'id, area_id, created_at, completed_at, auto_add_new_products, categories', + pickItems: + 'id, pick_list_id, product_id, status, is_carton, quantity, created_at, updated_at', + categories: 'id, name, created_at, updated_at', + }) + .upgrade(async (tx) => { + const pickLists = await tx.table('pickLists').toArray(); + + await Promise.all( + pickLists.map((pickList) => { + const updates: Partial = {}; + + if (!Array.isArray((pickList as PickList).categories)) { + updates.categories = []; + } + + if (typeof (pickList as PickList).auto_add_new_products !== 'boolean') { + updates.auto_add_new_products = false; + } + + if (Object.keys(updates).length === 0) return undefined; + + return tx.table('pickLists').update(pickList.id, updates); + }), + ); + }); } } diff --git a/src/models/PickList.ts b/src/models/PickList.ts index 8d08879..5643f52 100644 --- a/src/models/PickList.ts +++ b/src/models/PickList.ts @@ -4,4 +4,6 @@ export interface PickList { created_at: number; completed_at?: number; notes?: string; + categories: string[]; + auto_add_new_products: boolean; } diff --git a/src/screens/ActivePickListScreen.test.tsx b/src/screens/ActivePickListScreen.test.tsx index c68835c..df07382 100644 --- a/src/screens/ActivePickListScreen.test.tsx +++ b/src/screens/ActivePickListScreen.test.tsx @@ -84,7 +84,13 @@ vi.mock('../hooks/dataHooks', () => ({ updated_at: 0, }, ], - usePickList: () => ({ id: 'list-1', area_id: 'area-1', created_at: 0 }), + usePickList: () => ({ + id: 'list-1', + area_id: 'area-1', + created_at: 0, + categories: [], + auto_add_new_products: false, + }), useAreas: () => [{ id: 'area-1', name: 'Front Counter', created_at: 0, updated_at: 0 }], })); @@ -327,7 +333,7 @@ describe('ActivePickListScreen product search', () => { expect(itemLabels).toEqual(['Apple Juice', 'Chips', 'Cola', 'Cola']); }); - it('disables packaging filters and selects units when only unit packaging is present', () => { + it('disables packaging filters when only one packaging type is present', () => { pickItemsMock.mockReturnValue([ { id: 'item-1', @@ -349,38 +355,8 @@ describe('ActivePickListScreen product search', () => { , ); - expect(screen.getByRole('radio', { name: /all/i })).toBeDisabled(); expect(screen.getByRole('radio', { name: /cartons/i })).toBeDisabled(); - expect(screen.getByRole('radio', { name: /units/i })).toBeDisabled(); - expect(screen.getByRole('radio', { name: /units/i })).toBeChecked(); - }); - - it('disables packaging filters and selects cartons when only carton packaging is present', () => { - pickItemsMock.mockReturnValue([ - { - id: 'item-1', - pick_list_id: 'list-1', - product_id: 'prod-1', - quantity: 1, - is_carton: true, - status: 'pending', - created_at: 0, - updated_at: 0, - }, - ]); - - render( - - - } /> - - , - ); - - expect(screen.getByRole('radio', { name: /all/i })).toBeDisabled(); - expect(screen.getByRole('radio', { name: /cartons/i })).toBeDisabled(); - expect(screen.getByRole('radio', { name: /units/i })).toBeDisabled(); - expect(screen.getByRole('radio', { name: /cartons/i })).toBeChecked(); + expect(screen.getByRole('radio', { name: /units/i })).toBeEnabled(); }); it('resets the filter when the selected packaging type is unavailable', async () => { @@ -442,8 +418,6 @@ describe('ActivePickListScreen product search', () => { ); await waitFor(() => expect(screen.getByRole('radio', { name: /cartons/i })).toBeDisabled()); - expect(screen.getByRole('radio', { name: /all/i })).toBeDisabled(); - expect(screen.getByRole('radio', { name: /units/i })).toBeDisabled(); expect(screen.getByRole('radio', { name: /units/i })).toBeChecked(); }); diff --git a/src/screens/ActivePickListScreen.tsx b/src/screens/ActivePickListScreen.tsx index 944f2b4..048bbe2 100644 --- a/src/screens/ActivePickListScreen.tsx +++ b/src/screens/ActivePickListScreen.tsx @@ -100,11 +100,6 @@ export const ActivePickListScreen = () => { const hasCartonItems = useMemo(() => items.some((item) => item.is_carton), [items]); const hasUnitItems = useMemo(() => items.some((item) => !item.is_carton), [items]); - const packagingTypeCount = useMemo( - () => Number(hasCartonItems) + Number(hasUnitItems), - [hasCartonItems, hasUnitItems], - ); - const disablePackagingSelection = packagingTypeCount === 1; const filteredProducts = useMemo(() => { const normalizedQuery = query.trim().toLowerCase(); @@ -130,21 +125,12 @@ export const ActivePickListScreen = () => { }, [allItemsPicked, showPicked]); useEffect(() => { - if (packagingTypeCount === 1) { - const singlePackagingFilter = hasCartonItems ? 'cartons' : 'units'; - if (itemFilter !== singlePackagingFilter) { - setItemFilter(singlePackagingFilter); - } - - return; - } - if (itemFilter === 'cartons' && !hasCartonItems) { setItemFilter(hasUnitItems ? 'units' : 'all'); } else if (itemFilter === 'units' && !hasUnitItems) { setItemFilter(hasCartonItems ? 'cartons' : 'all'); } - }, [itemFilter, hasCartonItems, hasUnitItems, packagingTypeCount]); + }, [itemFilter, hasCartonItems, hasUnitItems]); const visibleItems = useMemo(() => { let filteredItems = showPicked @@ -335,23 +321,18 @@ export const ActivePickListScreen = () => { } sx={{ flexGrow: 1 }} > - } - label="All" - disabled={disablePackagingSelection} - /> + } label="All" /> } label="Cartons" - disabled={disablePackagingSelection || !hasCartonItems} + disabled={!hasCartonItems} /> } label="Units" - disabled={disablePackagingSelection || !hasUnitItems} + disabled={!hasUnitItems} /> diff --git a/src/screens/ManageProductsScreen.test.tsx b/src/screens/ManageProductsScreen.test.tsx index 1760063..fa3554c 100644 --- a/src/screens/ManageProductsScreen.test.tsx +++ b/src/screens/ManageProductsScreen.test.tsx @@ -11,6 +11,7 @@ const mockUseProducts = vi.fn(); const mockUseCategories = vi.fn(); const productDeleteMock = vi.fn(); const pickItemCountMock = vi.fn(); +const pickItemsStore: any[] = []; const mockDb = { products: { @@ -21,7 +22,12 @@ const mockDb = { }, pickItems: { where: vi.fn(), + add: vi.fn(), }, + pickLists: { + toArray: vi.fn(), + }, + transaction: vi.fn(), }; vi.mock('../hooks/dataHooks', () => ({ @@ -33,6 +39,10 @@ vi.mock('../context/DBProvider', () => ({ useDatabase: () => mockDb, })); +vi.mock('uuid', () => ({ + v4: () => 'new-product-id', +})); + vi.mock('../components/BarcodeScannerView', () => ({ BarcodeScannerView: ({ onDetected }: { onDetected?: (code: string) => void }) => (