87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import { useState, useCallback } from 'react';
|
|
import { db, Item } from '@/lib/db';
|
|
import { toast } from 'react-hot-toast';
|
|
import { syncOfflineOperations } from '@/lib/sync';
|
|
|
|
interface UseStockAdjustmentOptions {
|
|
selectedItem: Item | null;
|
|
isOnline: boolean;
|
|
currentUser: any;
|
|
onAdjustmentComplete?: () => void;
|
|
onInventoryUpdate?: (items: Item[]) => void;
|
|
}
|
|
|
|
export function useStockAdjustment(options: UseStockAdjustmentOptions) {
|
|
const { selectedItem, isOnline, currentUser, onAdjustmentComplete, onInventoryUpdate } = options;
|
|
const [adjustQty, setAdjustQty] = useState<number>(1);
|
|
const [adjustType, setAdjustType] = useState<'ADD' | 'REMOVE' | 'TRASH'>('ADD');
|
|
|
|
const handleAdjustStock = useCallback(async () => {
|
|
if (!selectedItem) return;
|
|
|
|
const toastId = toast.loading("Processing...");
|
|
|
|
try {
|
|
const finalAdjustQty = adjustQty;
|
|
const newQty = selectedItem.quantity + (adjustType === 'ADD' ? adjustQty : -adjustQty);
|
|
|
|
// Create a unique ID for this operation to prevent double-counting on server
|
|
const operationId = crypto.randomUUID();
|
|
|
|
// Queue local operation
|
|
const opType = adjustType === 'ADD' ? 'CHECK_IN' : (adjustType === 'TRASH' ? 'TRASH' : 'CHECK_OUT');
|
|
|
|
await db.pendingOperations.add({
|
|
type: opType as any,
|
|
barcode: selectedItem.barcode,
|
|
quantity: finalAdjustQty,
|
|
timestamp: Date.now(),
|
|
synced: 0,
|
|
uuid: operationId
|
|
} as any);
|
|
|
|
// Update local UI & DB
|
|
await db.items.update(selectedItem.id!, { quantity: newQty });
|
|
|
|
// Get updated inventory
|
|
const updated = await db.items.toArray();
|
|
if (onInventoryUpdate) {
|
|
onInventoryUpdate(updated);
|
|
}
|
|
|
|
// Trigger Sync
|
|
if (isOnline && currentUser) {
|
|
try {
|
|
const result = await syncOfflineOperations(currentUser.id);
|
|
if (result.success > 0) {
|
|
toast.success("Inventory updated & synced", { id: toastId });
|
|
} else {
|
|
toast.success("Saved locally", { id: toastId });
|
|
}
|
|
} catch (syncError) {
|
|
console.error("Sync failed:", syncError);
|
|
toast.success("Saved locally (Sync pending)", { id: toastId });
|
|
}
|
|
} else {
|
|
toast.success("Saved locally (Offline)", { id: toastId });
|
|
}
|
|
|
|
setAdjustQty(1);
|
|
if (onAdjustmentComplete) {
|
|
onAdjustmentComplete();
|
|
}
|
|
} catch (error: any) {
|
|
console.error("Adjustment failure:", error);
|
|
toast.error("Error saving operation", { id: toastId });
|
|
}
|
|
}, [selectedItem, adjustQty, adjustType, isOnline, currentUser, onAdjustmentComplete, onInventoryUpdate]);
|
|
|
|
return {
|
|
adjustQty,
|
|
setAdjustQty,
|
|
adjustType,
|
|
setAdjustType,
|
|
handleAdjustStock
|
|
};
|
|
}
|