[dyad] Item selection dropdown added to Purchase Order form - wrote 1 file(s)
This commit is contained in:
parent
2c3bf04d15
commit
0dc7ffb925
1 changed files with 70 additions and 26 deletions
|
|
@ -28,8 +28,8 @@ import pb from "@/lib/pocketbase"
|
|||
|
||||
// Define the schema for a single item in the purchase order
|
||||
const itemSchema = z.object({
|
||||
stockItemId: z.string(),
|
||||
itemName: z.string(),
|
||||
stockItemId: z.string().min(1, { message: "Stock item ID is required." }),
|
||||
itemName: z.string().min(1, { message: "Item name is required." }),
|
||||
quantity: z.number().int().positive(),
|
||||
sku: z.string(),
|
||||
costPrice: z.number(),
|
||||
|
|
@ -56,8 +56,17 @@ type Supplier = {
|
|||
name: string
|
||||
}
|
||||
|
||||
// Define the type for a stock item
|
||||
type StockItem = {
|
||||
id: string
|
||||
name: string
|
||||
sku: string
|
||||
costPrice: number
|
||||
}
|
||||
|
||||
export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormProps) {
|
||||
const [suppliers, setSuppliers] = useState<Supplier[]>([]) // State to hold suppliers
|
||||
const [stockItems, setStockItems] = useState<StockItem[]>([]) // State to hold stock items
|
||||
|
||||
// Fetch suppliers when the component mounts
|
||||
const fetchSuppliers = useCallback(async () => {
|
||||
|
|
@ -76,9 +85,29 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
}
|
||||
}, []);
|
||||
|
||||
// Fetch stock items when the component mounts
|
||||
const fetchStockItems = useCallback(async () => {
|
||||
try {
|
||||
const records = await pb.collection('stock_items').getList(1, 50, {
|
||||
sort: '-created',
|
||||
});
|
||||
const formattedStockItems: StockItem[] = records.items.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
sku: item.sku,
|
||||
costPrice: item.cost_price, // Assuming cost_price is the field in stock_items
|
||||
}));
|
||||
setStockItems(formattedStockItems);
|
||||
} catch (error) {
|
||||
console.error("Error fetching stock items:", error);
|
||||
showError("Failed to load stock items.");
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchSuppliers();
|
||||
}, [fetchSuppliers]);
|
||||
fetchStockItems();
|
||||
}, [fetchSuppliers, fetchStockItems]);
|
||||
|
||||
const form = useForm<z.infer<typeof purchaseOrderFormSchema>>({
|
||||
resolver: zodResolver(purchaseOrderFormSchema),
|
||||
|
|
@ -115,12 +144,9 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
}
|
||||
|
||||
// Function to handle changes in item fields
|
||||
// Explicitly type 'field' to be a key of ItemSchemaType
|
||||
const handleItemChange = (index: number, field: keyof ItemSchemaType, value: any) => {
|
||||
const currentItems = form.getValues("items");
|
||||
const newItems = [...currentItems];
|
||||
|
||||
// Type assertion for newItems[index] to ensure it's treated as a mutable object
|
||||
const currentItem = newItems[index] as ItemSchemaType;
|
||||
|
||||
if (field === "quantity") {
|
||||
|
|
@ -130,10 +156,26 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
} else {
|
||||
currentItem[field] = value;
|
||||
}
|
||||
newItems[index] = currentItem; // Assign the updated item back to the array
|
||||
newItems[index] = currentItem;
|
||||
form.setValue("items", newItems);
|
||||
}
|
||||
|
||||
// Function to handle stock item selection from dropdown
|
||||
const handleStockItemSelect = (index: number, selectedItemName: string) => {
|
||||
const selectedStockItem = stockItems.find(item => item.name === selectedItemName);
|
||||
if (selectedStockItem) {
|
||||
// Update the form fields with the selected stock item's details
|
||||
handleItemChange(index, "stockItemId", selectedStockItem.id);
|
||||
handleItemChange(index, "itemName", selectedStockItem.name);
|
||||
handleItemChange(index, "sku", selectedStockItem.sku);
|
||||
handleItemChange(index, "costPrice", selectedStockItem.costPrice);
|
||||
// Quantity remains as is or defaults to 1 if not set
|
||||
if (form.getValues("items")[index].quantity === 0) {
|
||||
handleItemChange(index, "quantity", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmit(values: z.infer<typeof purchaseOrderFormSchema>) {
|
||||
try {
|
||||
// Find the selected supplier's ID
|
||||
|
|
@ -149,18 +191,6 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
supplier: selectedSupplier.id, // This will be the relation to the suppliers collection
|
||||
orderDate: values.orderDate.toISOString(),
|
||||
status: "Pending Approval",
|
||||
items: values.items.map(item => ({
|
||||
stockItemId: item.stockItemId,
|
||||
quantity: item.quantity,
|
||||
// You might need to adjust this based on how you store item details in purchase_orders
|
||||
})),
|
||||
// PocketBase expects an array of item IDs and quantities separately if using relations
|
||||
// For simplicity here, we'll store item details directly in the purchase_order record
|
||||
// If you have a separate 'purchase_order_items' collection, you'd create records there.
|
||||
// For now, let's assume we're embedding item details.
|
||||
// We need to map the item details to match what's expected by the 'purchase_orders' collection.
|
||||
// The 'items' field in 'purchase_orders' is likely an array of objects.
|
||||
// Let's assume it expects { stockItemId: string, quantity: number, itemName: string, sku: string, costPrice: number }
|
||||
embedded_items: values.items.map(item => ({
|
||||
stockItemId: item.stockItemId,
|
||||
itemName: item.itemName,
|
||||
|
|
@ -168,7 +198,7 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
sku: item.sku,
|
||||
costPrice: item.costPrice,
|
||||
})),
|
||||
quantities: values.items.map(item => item.quantity), // Keep quantities array as well if needed elsewhere
|
||||
quantities: values.items.map(item => item.quantity),
|
||||
};
|
||||
|
||||
await pb.collection('purchase_orders').create(purchaseOrderData);
|
||||
|
|
@ -192,8 +222,7 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
<FormItem>
|
||||
<FormLabel>Supplier</FormLabel>
|
||||
<Select onValueChange={(value) => {
|
||||
field.onChange(value); // Update form state with the selected supplier name
|
||||
// You might want to also set the supplier ID here if needed for the relation
|
||||
field.onChange(value);
|
||||
}} value={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
|
|
@ -243,9 +272,23 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Item Name</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} onChange={(e) => handleItemChange(index, "itemName", e.target.value)} />
|
||||
</FormControl>
|
||||
<Select
|
||||
onValueChange={(selectedValue) => handleStockItemSelect(index, selectedValue)}
|
||||
value={field.value} // Set the current value of the item name
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select item" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{stockItems.map((stockItem) => (
|
||||
<SelectItem key={stockItem.id} value={stockItem.name}>
|
||||
{stockItem.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -257,7 +300,8 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro
|
|||
<FormItem>
|
||||
<FormLabel>SKU</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} onChange={(e) => handleItemChange(index, "sku", e.target.value)} />
|
||||
{/* Display SKU, but it's managed by handleStockItemSelect */}
|
||||
<Input {...field} readOnly placeholder="SKU" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
Loading…
Reference in a new issue