Преглед изворни кода

fix stock take efficient

MergeProblem1
CANCERYS\kw093 пре 1 недеља
родитељ
комит
7079e2f9d0
4 измењених фајлова са 53 додато и 83 уклоњено
  1. +17
    -0
      src/app/api/stockTake/actions.ts
  2. +1
    -1
      src/components/DoWorkbench/GoodPickExecutionWorkbenchRecord.tsx
  3. +17
    -18
      src/components/PickOrderSearch/WorkbenchPickExecution.tsx
  4. +18
    -64
      src/components/StockTakeManagement/ApproverStockTakeAll.tsx

+ 17
- 0
src/app/api/stockTake/actions.ts Прегледај датотеку

@@ -394,6 +394,11 @@ export interface BatchSaveApproverStockTakeAllRequest {
sectionDescription?: string | null;
stockTakeSections?: string | null; // 逗號字串
}
export interface BatchSaveApproverStockTakeByIdsRequest {
stockTakeId: number;
approverId: number;
recordIds: number[];
}
export const saveApproverStockTakeRecord = async (
request: SaveApproverStockTakeRecordRequest,
stockTakeId: number
@@ -451,6 +456,18 @@ export const batchSaveApproverStockTakeRecordsAll = cache(async (data: BatchSave
return r
})

export const batchSaveApproverStockTakeRecordsByIds = cache(async (data: BatchSaveApproverStockTakeByIdsRequest) => {
const r = await serverFetchJson<BatchSaveApproverStockTakeRecordResponse>(
`${BASE_API_URL}/stockTakeRecord/batchSaveApproverStockTakeRecordsByIds`,
{
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
}
)
return r
})

export const updateStockTakeRecordStatusToNotMatch = async (
stockTakeRecordId: number
) => {


+ 1
- 1
src/components/DoWorkbench/GoodPickExecutionWorkbenchRecord.tsx Прегледај датотеку

@@ -488,7 +488,7 @@ const GoodPickExecutionWorkbenchRecord: React.FC<Props> = ({
criteria={searchCriteria}
onSearch={handleSearch}
onReset={handleSearchReset}
searchQuery={searchQuery}
// searchQuery={searchQuery}
/>
</Box>
<Stack


+ 17
- 18
src/components/PickOrderSearch/WorkbenchPickExecution.tsx Прегледај датотеку

@@ -36,7 +36,6 @@ import {
type PickOrderLotDetailResponse,
} from "@/app/api/pickOrder/actions";
import { workbenchScanPick } from "@/app/api/doworkbench/actions";
import { workbenchScanPickResponseNeedsFullRefresh } from "@/app/api/doworkbench/workbenchScanPickUtils";
import { fetchStockInLineInfo } from "@/app/api/po/actions";
import WorkbenchLotLabelPrintModal from "@/components/DoWorkbench/WorkbenchLotLabelPrintModal";
import TestQrCodeProvider from "../QrCodeScannerProvider/TestQrCodeProvider";
@@ -584,26 +583,26 @@ const WorkbenchPickExecution: React.FC<Props> = ({ filterArgs }) => {
...(typeof qtyValue === "number" && Number.isFinite(qtyValue) ? { qty: qtyValue } : {}),
userId,
});
const errMsg = localizeBackendMessage(res.message, "Scan pick failed");
setError(errMsg);
setQrScanErrorMsg(errMsg);
const ok = String(res.code || "").toUpperCase() === "SUCCESS";
if (!ok) {
const errMsg = localizeBackendMessage(res.message, "Scan pick failed");
setError(errMsg);
setQrScanErrorMsg(errMsg);
startTransition(() => {
setQrScanError(true);
setQrScanSuccess(false);
});
return;
}
const okMsg = localizeBackendMessage(res.message, "Scan pick success");
setMessage(okMsg);
setQrScanSuccessMsg(okMsg);
if (workbenchScanPickResponseNeedsFullRefresh(res)) {
if (selectedPickOrderId != null && selectedPickOrderLineId != null && selectedTopMeta) {
await loadLineDetailV2(selectedPickOrderId, selectedPickOrderLineId, selectedTopMeta);
}
} else {
const entity = res.entity as any;
setLotRows((prev) =>
prev.map((r) =>
r.stockOutLineId === row.stockOutLineId
? { ...r, status: toStr(entity?.status || r.status), pickedQty: toNum(entity?.qty, r.pickedQty) }
: r,
),
);
startTransition(() => {
setQrScanError(false);
setQrScanSuccess(true);
});
if (selectedPickOrderId != null && selectedPickOrderLineId != null && selectedTopMeta) {
await loadLineDetailV2(selectedPickOrderId, selectedPickOrderLineId, selectedTopMeta);
}
setWorkbenchLotLabelModalOpen(false);
setWorkbenchLotLabelContextLot(null);


+ 18
- 64
src/components/StockTakeManagement/ApproverStockTakeAll.tsx Прегледај датотеку

@@ -31,6 +31,7 @@ import {
InventoryLotDetailResponse,
SaveApproverStockTakeRecordRequest,
saveApproverStockTakeRecord,
batchSaveApproverStockTakeRecordsByIds,
getApproverInventoryLotDetailsAllPending,
getApproverInventoryLotDetailsAllApproved,
updateStockTakeRecordStatusToNotMatch,
@@ -745,75 +746,32 @@ const ApproverStockTakeAll: React.FC<ApproverStockTakeAllProps> = ({
}

setBatchSaving(true);
let successCount = 0;
let skippedApproverEmpty = 0;
let errorCount = 0;

try {
for (const detail of sortedDetails) {
if (detail.stockTakeRecordStatus === "completed") {
continue;
}
const recordIds = sortedDetails
.map((d) => d.stockTakeRecordId)
.filter((id): id is number => typeof id === "number" && id > 0);

const built = buildApproverSaveRequest(
detail,
qtySelection,
approverQty,
approverBadQty,
currentUserId,
t
);
if (!built.ok) {
if (built.reason === "skip_approver_empty") {
skippedApproverEmpty += 1;
continue;
}
errorCount += 1;
continue;
}

try {
await saveApproverStockTakeRecord(built.request, selectedSession.stockTakeId);
successCount += 1;
const { goodQty, finalQty, finalBadQty, selection } = built;
setInventoryLotDetails((prev) =>
prev.map((d) =>
d.id === detail.id
? {
...d,
finalQty: goodQty,
approverQty: selection === "approver" ? finalQty : d.approverQty,
approverBadQty: selection === "approver" ? finalBadQty : d.approverBadQty,
stockTakeRecordStatus: "completed",
}
: d
)
);
} catch (e: any) {
errorCount += 1;
let msg = e?.message || t("Failed to save approver stock take record");
if (e?.response) {
try {
const errorData = await e.response.json();
msg = errorData.message || errorData.error || msg;
} catch {
/* ignore */
}
}
console.error("Batch save row failed", detail.id, msg);
}
if (recordIds.length === 0) {
onSnackbar(t("No valid records to batch save"), "warning");
return;
}

const result = await batchSaveApproverStockTakeRecordsByIds({
stockTakeId: selectedSession.stockTakeId,
approverId: currentUserId,
recordIds,
});

onSnackbar(
t("Batch approver save completed: {{success}} success, {{skipped}} skipped, {{errors}} errors", {
success: successCount,
skipped: skippedApproverEmpty,
errors: errorCount,
t("Batch approver save completed: {{success}} success, {{errors}} errors", {
success: result.successCount,
errors: result.errorCount,
}),
errorCount > 0 ? "warning" : "success"
result.errorCount > 0 ? "warning" : "success"
);

if (appliedFilters && successCount > 0) {
if (appliedFilters && result.successCount > 0) {
await loadDetails(appliedFilters);
}
} catch (e: any) {
@@ -835,10 +793,6 @@ const ApproverStockTakeAll: React.FC<ApproverStockTakeAllProps> = ({
mode,
appliedFilters,
inventoryLotDetails.length,
sortedDetails,
qtySelection,
approverQty,
approverBadQty,
]);

const formatNumber = (num: number | null | undefined): string => {


Loading…
Откажи
Сачувај