Add carton flag to pick item quantity handling

This commit is contained in:
beatz174-bit committed 2025-11-23 11:59:53 +10:00
1 parent 64acab1cf2
commit 5d17bb2609
3 files changed
+50 -20

No files matched your search

+12 -7
View File
@@ -7,8 +7,8 @@ import { useSwipe } from '../hooks/useSwipe';
interface PickItemRowProps { interface PickItemRowProps {
item: PickItem; item: PickItem;
product?: Product | null; product?: Product | null;
onIncrementUnit: () => void; onIncrementQuantity: () => void;
onIncrementBulk: () => void; onToggleCarton: () => void;
onSwipeLeft: () => void; onSwipeLeft: () => void;
onSwipeRight: () => void; onSwipeRight: () => void;
} }
@@ -22,14 +22,16 @@ const statusColor: Record<PickItemStatus, 'default' | 'success' | 'warning'> = {
export const PickItemRow = ({ export const PickItemRow = ({
item, item,
product, product,
onIncrementUnit, onIncrementQuantity,
onIncrementBulk, onToggleCarton,
onSwipeLeft, onSwipeLeft,
onSwipeRight, onSwipeRight,
}: PickItemRowProps) => { }: PickItemRowProps) => {
const longPressHandlers = useLongPress({ onLongPress: onIncrementBulk, onClick: onIncrementUnit }); const longPressHandlers = useLongPress({ onLongPress: onToggleCarton, onClick: onIncrementQuantity });
const swipeHandlers = useSwipe({ onSwipeLeft, onSwipeRight }); const swipeHandlers = useSwipe({ onSwipeLeft, onSwipeRight });
const isCarton = item.quantity_bulk > 0;
return ( return (
<Stack <Stack
direction="row" direction="row"
@@ -43,10 +45,13 @@ export const PickItemRow = ({
<div> <div>
<Typography variant="subtitle1">{product?.name ?? 'Unknown product'}</Typography> <Typography variant="subtitle1">{product?.name ?? 'Unknown product'}</Typography>
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary">
{item.quantity_units} units / {item.quantity_bulk} bulk Qty: {item.quantity_units}
</Typography> </Typography>
</div> </div>
<Chip label={item.status} color={statusColor[item.status]} size="small" /> <Stack direction="row" spacing={1} alignItems="center">
{isCarton ? <Chip label="Carton" color="primary" size="small" /> : null}
<Chip label={item.status} color={statusColor[item.status]} size="small" />
</Stack>
</Stack> </Stack>
); );
}; };
+5 -5
View File
@@ -19,7 +19,7 @@ export const ActivePickListScreen = () => {
[areas, pickList?.area_id], [areas, pickList?.area_id],
); );
const handleIncrementUnit = async (itemId: string) => { const handleIncrementQuantity = async (itemId: string) => {
const existing = await db.pickItems.get(itemId); const existing = await db.pickItems.get(itemId);
if (!existing) return; if (!existing) return;
await db.pickItems.update(itemId, { await db.pickItems.update(itemId, {
@@ -28,11 +28,11 @@ export const ActivePickListScreen = () => {
}); });
}; };
const handleIncrementBulk = async (itemId: string) => { const handleToggleCarton = async (itemId: string) => {
const existing = await db.pickItems.get(itemId); const existing = await db.pickItems.get(itemId);
if (!existing) return; if (!existing) return;
await db.pickItems.update(itemId, { await db.pickItems.update(itemId, {
quantity_bulk: existing.quantity_bulk + 1, quantity_bulk: existing.quantity_bulk > 0 ? 0 : 1,
updated_at: Date.now(), updated_at: Date.now(),
}); });
}; };
@@ -68,8 +68,8 @@ export const ActivePickListScreen = () => {
key={item.id} key={item.id}
item={item} item={item}
product={products.find((p) => p.id === item.product_id)} product={products.find((p) => p.id === item.product_id)}
onIncrementUnit={() => handleIncrementUnit(item.id)} onIncrementQuantity={() => handleIncrementQuantity(item.id)}
onIncrementBulk={() => handleIncrementBulk(item.id)} onToggleCarton={() => handleToggleCarton(item.id)}
onSwipeLeft={() => handleSwipeLeft(item.id)} onSwipeLeft={() => handleSwipeLeft(item.id)}
onSwipeRight={() => handleSwipeRight(item.id)} onSwipeRight={() => handleSwipeRight(item.id)}
/> />
+33 -8
View File
@@ -1,17 +1,18 @@
import { import {
Autocomplete, Autocomplete,
Button, Button,
Checkbox,
Container, Container,
FormControlLabel,
InputAdornment,
Stack, Stack,
TextField, TextField,
Typography, Typography,
InputAdornment,
} from '@mui/material'; } from '@mui/material';
import SearchIcon from '@mui/icons-material/Search'; import SearchIcon from '@mui/icons-material/Search';
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { NumericStepper } from '../components/NumericStepper';
import { usePickItems, useProducts } from '../hooks/dataHooks'; import { usePickItems, useProducts } from '../hooks/dataHooks';
import { useDatabase } from '../context/DBProvider'; import { useDatabase } from '../context/DBProvider';
@@ -22,8 +23,8 @@ export const AddItemScreen = () => {
const products = useProducts(); const products = useProducts();
const [selectedProduct, setSelectedProduct] = useState<typeof products[number] | null>(null); const [selectedProduct, setSelectedProduct] = useState<typeof products[number] | null>(null);
const [query, setQuery] = useState(''); const [query, setQuery] = useState('');
const [units, setUnits] = useState(1); const [quantity, setQuantity] = useState(1);
const [bulk, setBulk] = useState(0); const [isCarton, setIsCarton] = useState(false);
const navigate = useNavigate(); const navigate = useNavigate();
const existingProductIds = useMemo( const existingProductIds = useMemo(
@@ -53,6 +54,16 @@ export const AddItemScreen = () => {
} }
}, [filteredProducts, selectedProduct]); }, [filteredProducts, selectedProduct]);
useEffect(() => {
setQuantity(1);
setIsCarton(false);
}, [selectedProduct]);
const quantityHelperText = selectedProduct?.unit_type
? `Enter ${selectedProduct.unit_type} to pick`
: 'Enter the quantity to pick';
const cartonLabel = selectedProduct?.bulk_name ? `Carton (${selectedProduct.bulk_name})` : 'Carton';
const addItem = async () => { const addItem = async () => {
const productId = selectedProduct?.id; const productId = selectedProduct?.id;
@@ -61,8 +72,8 @@ export const AddItemScreen = () => {
id: uuidv4(), id: uuidv4(),
pick_list_id: id, pick_list_id: id,
product_id: productId, product_id: productId,
quantity_units: units, quantity_units: quantity,
quantity_bulk: bulk, quantity_bulk: isCarton ? 1 : 0,
status: 'pending', status: 'pending',
created_at: Date.now(), created_at: Date.now(),
updated_at: Date.now(), updated_at: Date.now(),
@@ -113,8 +124,22 @@ export const AddItemScreen = () => {
/> />
)} )}
/> />
<NumericStepper label="Units" value={units} onChange={setUnits} /> <TextField
<NumericStepper label="Bulk" value={bulk} onChange={setBulk} /> label="Quantity"
type="number"
inputProps={{ min: 1 }}
value={quantity}
onChange={(event) => {
const value = Number(event.target.value);
setQuantity(Number.isNaN(value) || value < 1 ? 1 : value);
}}
helperText={quantityHelperText}
fullWidth
/>
<FormControlLabel
control={<Checkbox checked={isCarton} onChange={(event) => setIsCarton(event.target.checked)} />}
label={cartonLabel}
/>
<Button variant="contained" disabled={!selectedProduct} onClick={addItem}> <Button variant="contained" disabled={!selectedProduct} onClick={addItem}>
Add to List Add to List
</Button> </Button>