feat: 完成進貨單自動拋轉應付帳款流程與AP介面優化
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 1m8s
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 1m8s
1. 新增 AccountPayable (應付帳款) 模組,包含 Migration、Model、Service 與 Controller 2. 修改 GoodsReceipt (進貨單) 流程,在確認進貨時自動產生對應的應付帳款單 (AP-YYYYMMDD-XX) 3. 實作應付帳款詳細頁面 (Show.tsx),包含發票登記與標記付款功能 4. 修正應付帳款 Show 頁面的排版,將發票資訊套用標準的綠色背景區塊,並調整按鈕位置 5. 更新相關的 Service Provider 與 Routes
This commit is contained in:
@@ -81,58 +81,74 @@ export default function Index({
|
||||
setPerPage(filters.per_page || "10");
|
||||
}, [filters]);
|
||||
|
||||
const applyFilters = useCallback(
|
||||
(overrides: Record<string, string> = {}) => {
|
||||
const params: Record<string, string> = {
|
||||
search: searchTerm,
|
||||
status: statusFilter === "all" ? "" : statusFilter,
|
||||
warehouse_id: warehouseFilter === "all" ? "" : warehouseFilter,
|
||||
per_page: perPage,
|
||||
...overrides,
|
||||
};
|
||||
// 清理空值
|
||||
Object.keys(params).forEach((key) => {
|
||||
if (!params[key]) delete params[key];
|
||||
});
|
||||
const debouncedFilter = useCallback(
|
||||
debounce((params: any) => {
|
||||
router.get(route("store-requisitions.index"), params, {
|
||||
preserveState: true,
|
||||
replace: true,
|
||||
preserveScroll: true,
|
||||
});
|
||||
},
|
||||
[searchTerm, statusFilter, warehouseFilter, perPage]
|
||||
);
|
||||
|
||||
const debouncedSearch = useCallback(
|
||||
debounce((term: string) => {
|
||||
applyFilters({ search: term });
|
||||
}, 500),
|
||||
[applyFilters]
|
||||
}, 300),
|
||||
[]
|
||||
);
|
||||
|
||||
const handleSearchChange = (term: string) => {
|
||||
setSearchTerm(term);
|
||||
debouncedSearch(term);
|
||||
debouncedFilter({
|
||||
...filters,
|
||||
search: term,
|
||||
status: statusFilter === "all" ? "" : statusFilter,
|
||||
warehouse_id: warehouseFilter === "all" ? "" : warehouseFilter,
|
||||
page: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const handleClearSearch = () => {
|
||||
setSearchTerm("");
|
||||
applyFilters({ search: "" });
|
||||
debouncedFilter({
|
||||
...filters,
|
||||
search: "",
|
||||
status: statusFilter === "all" ? "" : statusFilter,
|
||||
warehouse_id: warehouseFilter === "all" ? "" : warehouseFilter,
|
||||
page: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const handleStatusChange = (value: string) => {
|
||||
setStatusFilter(value);
|
||||
applyFilters({ status: value === "all" ? "" : value });
|
||||
debouncedFilter({
|
||||
...filters,
|
||||
search: searchTerm,
|
||||
status: value === "all" ? "" : value,
|
||||
warehouse_id: warehouseFilter === "all" ? "" : warehouseFilter,
|
||||
page: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const handleWarehouseChange = (value: string) => {
|
||||
setWarehouseFilter(value);
|
||||
applyFilters({ warehouse_id: value === "all" ? "" : value });
|
||||
debouncedFilter({
|
||||
...filters,
|
||||
search: searchTerm,
|
||||
status: statusFilter === "all" ? "" : statusFilter,
|
||||
warehouse_id: value === "all" ? "" : value,
|
||||
page: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const handlePerPageChange = (value: string) => {
|
||||
setPerPage(value);
|
||||
applyFilters({ per_page: value });
|
||||
router.get(
|
||||
route("store-requisitions.index"),
|
||||
{
|
||||
...filters,
|
||||
search: searchTerm,
|
||||
status: statusFilter === "all" ? "" : statusFilter,
|
||||
warehouse_id: warehouseFilter === "all" ? "" : warehouseFilter,
|
||||
per_page: value,
|
||||
page: 1,
|
||||
},
|
||||
{ preserveState: true, replace: true, preserveScroll: true }
|
||||
);
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
|
||||
Reference in New Issue
Block a user