feat: add void action to inventory count index
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 1m9s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped

This commit is contained in:
2026-01-29 13:12:02 +08:00
parent 56e30a85bb
commit a31c8d6052
2 changed files with 85 additions and 21 deletions

View File

@@ -31,14 +31,26 @@ import {
X, X,
ClipboardCheck, ClipboardCheck,
Eye, Eye,
Pencil Pencil,
Trash2
} from 'lucide-react'; } from 'lucide-react';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/Components/ui/alert-dialog";
import Pagination from '@/Components/shared/Pagination'; import Pagination from '@/Components/shared/Pagination';
import { Can } from '@/Components/Permission/Can'; import { Can } from '@/Components/Permission/Can';
export default function Index({ auth, docs, warehouses, filters }: any) { export default function Index({ auth, docs, warehouses, filters }: any) {
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
const { data, setData, post, processing, reset, errors } = useForm({ const [deleteId, setDeleteId] = useState<string | null>(null);
const { data, setData, post, processing, reset, errors, delete: destroy } = useForm({
warehouse_id: '', warehouse_id: '',
remarks: '', remarks: '',
}); });
@@ -108,6 +120,19 @@ export default function Index({ auth, docs, warehouses, filters }: any) {
}); });
}; };
const confirmDelete = (id: string) => {
setDeleteId(id);
};
const handleDelete = () => {
if (deleteId) {
destroy(route('inventory.count.destroy', [deleteId]), {
onSuccess: () => setDeleteId(null),
onError: () => setDeleteId(null),
});
}
};
const getStatusBadge = (status) => { const getStatusBadge = (status) => {
switch (status) { switch (status) {
case 'draft': case 'draft':
@@ -115,7 +140,7 @@ export default function Index({ auth, docs, warehouses, filters }: any) {
case 'counting': case 'counting':
return <Badge className="bg-blue-500 hover:bg-blue-600"></Badge>; return <Badge className="bg-blue-500 hover:bg-blue-600"></Badge>;
case 'completed': case 'completed':
return <Badge className="bg-green-500 hover:bg-green-600"></Badge>; return <Badge className="bg-green-500 hover:bg-green-600"></Badge>;
case 'cancelled': case 'cancelled':
return <Badge variant="destructive"></Badge>; return <Badge variant="destructive"></Badge>;
default: default:
@@ -285,12 +310,23 @@ export default function Index({ auth, docs, warehouses, filters }: any) {
title={doc.status === 'completed' ? '查閱' : '盤點'} title={doc.status === 'completed' ? '查閱' : '盤點'}
> >
{doc.status === 'completed' ? ( {doc.status === 'completed' ? (
<Eye className="w-4 h-4" /> <Eye className="w-4 h-4 ml-0.5" />
) : ( ) : (
<Pencil className="w-4 h-4" /> <Pencil className="w-4 h-4 ml-0.5" />
)} )}
</Button> </Button>
</Link> </Link>
{doc.status !== 'completed' && (
<Button
variant="outline"
size="sm"
className="button-outlined-error"
title="作廢"
onClick={() => confirmDelete(doc.id)}
>
<Trash2 className="w-4 h-4 ml-0.5" />
</Button>
)}
</Can> </Can>
</div> </div>
</TableCell> </TableCell>
@@ -323,6 +359,21 @@ export default function Index({ auth, docs, warehouses, filters }: any) {
</div> </div>
<Pagination links={docs.links} /> <Pagination links={docs.links} />
</div> </div>
<AlertDialog open={!!deleteId} onOpenChange={(open) => !open && setDeleteId(null)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction onClick={handleDelete} className="bg-red-600 hover:bg-red-700"></AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div> </div>
</AuthenticatedLayout> </AuthenticatedLayout>
); );

View File

@@ -1,5 +1,5 @@
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'; import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { Head, useForm, Link } from '@inertiajs/react'; // Added Link import { Head, useForm, Link, router } from '@inertiajs/react'; // Added Link
import { import {
Table, Table,
TableBody, TableBody,
@@ -56,11 +56,9 @@ export default function Show({ doc }: any) {
}; };
const handleReopen = () => { const handleReopen = () => {
if (confirm('確定要取消核准嗎?單據將回復為盤點中狀態,且庫存異動將被撤回(若已過帳)。')) { router.visit(route('inventory.count.reopen', [doc.id]), {
router.visit(route('inventory.count.reopen', [doc.id]), { method: 'put',
method: 'put', });
});
}
} }
const isCompleted = doc.status === 'completed'; const isCompleted = doc.status === 'completed';
@@ -123,16 +121,31 @@ export default function Show({ doc }: any) {
{isCompleted && ( {isCompleted && (
<Can permission="inventory.adjust"> <Can permission="inventory.adjust">
<Button <AlertDialog>
variant="outline" <AlertDialogTrigger asChild>
size="sm" <Button
className="button-outlined-error" variant="outline"
onClick={handleReopen} size="sm"
disabled={processing} className="button-outlined-error"
> disabled={processing}
<RotateCcw className="w-4 h-4 mr-2" /> >
<RotateCcw className="w-4 h-4 mr-2" />
</Button>
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction onClick={handleReopen} className="bg-red-600 hover:bg-red-700"></AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</Can> </Can>
)} )}