summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImanuel Marinao <imanuel.mariano.5@gmail.com>2024-07-04 13:40:28 +0700
committerImanuel Marinao <imanuel.mariano.5@gmail.com>2024-07-04 13:40:28 +0700
commitd0c00e30f3f850f8452397db05f41e0c0ecef3f9 (patch)
tree5a7a04fc6ac2480269b99c2a8fc21ab4b917731f
parent9a80c0a767c6a35a489b9d45654ae60f7ddc6794 (diff)
<iman> update stock opname
-rw-r--r--src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx142
-rw-r--r--src/app/api/stock-opname/route.tsx231
-rw-r--r--src/modules/result/components/Table.tsx278
3 files changed, 288 insertions, 363 deletions
diff --git a/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx b/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx
index cf76ac3..c533392 100644
--- a/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx
+++ b/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx
@@ -1,12 +1,12 @@
-import { StockOpnameLocationRes } from "@/common/types/stockOpname"
-import { NextRequest, NextResponse } from "next/server"
-import { prisma } from "prisma/client"
-import { Team } from "prisma/generated/client"
-import _ from "lodash"
+import { StockOpnameLocationRes } from "@/common/types/stockOpname";
+import { NextRequest, NextResponse } from "next/server";
+import { prisma } from "prisma/client";
+import { Team } from "prisma/generated/client";
+import _ from "lodash";
-type PostParams = { params: { companyId: string, productId: string } }
+type PostParams = { params: { companyId: string; productId: string } };
-const SELF_HOST = process.env.SELF_HOST as string
+const SELF_HOST = process.env.SELF_HOST as string;
export async function POST(request: NextRequest, { params }: PostParams) {
const totalQty: { [key in keyof typeof Team]: number | 0 } = {
@@ -14,75 +14,61 @@ export async function POST(request: NextRequest, { params }: PostParams) {
COUNT2: 0,
COUNT3: 0,
VERIFICATION: 0,
- }
+ };
const searchParams = new URLSearchParams({
companyId: params.companyId.toString(),
- productId: params.productId.toString()
- })
+ productId: params.productId.toString(),
+ });
- const stockOpnamesFetch = await fetch(`${SELF_HOST}/api/stock-opname/location?${searchParams}`)
- console.log("stockOpnamesFetch",stockOpnamesFetch)
- const stockOpnames: StockOpnameLocationRes[] = await stockOpnamesFetch.json()
- console.log("stockOpnames",stockOpnames)
+ const stockOpnamesFetch = await fetch(`${SELF_HOST}/api/stock-opname/location?${searchParams}`);
+ console.log("stockOpnamesFetch", stockOpnamesFetch);
+ const stockOpnames: StockOpnameLocationRes[] = await stockOpnamesFetch.json();
+ console.log("stockOpnames", stockOpnames);
- let isDifferent: boolean = false
- let verificationCounter: number = 0
+ let isDifferent: boolean = false;
+ let verificationCounter: number = 0;
for (const opname of stockOpnames) {
- let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname
-
- if (totalQty['COUNT1'] === null && _.isNumber(COUNT1.quantity)) totalQty['COUNT1'] = 0
- if (totalQty['COUNT2'] === null && _.isNumber(COUNT2.quantity)) totalQty['COUNT2'] = 0
- if (totalQty['COUNT3'] === null && _.isNumber(COUNT3.quantity)) totalQty['COUNT3'] = 0
- if (totalQty['VERIFICATION'] === null && _.isNumber(VERIFICATION.quantity)) totalQty['VERIFICATION'] = 0
+ let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
- if (_.isNumber(COUNT1.quantity)) totalQty['COUNT1'] = (totalQty['COUNT1'] || 0) + COUNT1.quantity;
- if (_.isNumber(COUNT2.quantity)) totalQty['COUNT2'] = (totalQty['COUNT2'] || 0) + COUNT2.quantity;
- if (_.isNumber(COUNT3.quantity)) totalQty['COUNT3'] = (totalQty['COUNT3'] || 0) + COUNT3.quantity;
- if (_.isNumber(VERIFICATION.quantity)) totalQty['VERIFICATION'] = (totalQty['VERIFICATION'] || 0) + VERIFICATION.quantity;
+ if (totalQty["COUNT1"] === null && _.isNumber(COUNT1.quantity)) totalQty["COUNT1"] = 0;
+ if (totalQty["COUNT2"] === null && _.isNumber(COUNT2.quantity)) totalQty["COUNT2"] = 0;
+ if (totalQty["COUNT3"] === null && _.isNumber(COUNT3.quantity)) totalQty["COUNT3"] = 0;
+ if (totalQty["VERIFICATION"] === null && _.isNumber(VERIFICATION.quantity)) totalQty["VERIFICATION"] = 0;
+ if (_.isNumber(COUNT1.quantity)) totalQty["COUNT1"] = (totalQty["COUNT1"] || 0) + COUNT1.quantity;
+ if (_.isNumber(COUNT2.quantity)) totalQty["COUNT2"] = (totalQty["COUNT2"] || 0) + COUNT2.quantity;
+ if (_.isNumber(COUNT3.quantity)) totalQty["COUNT3"] = (totalQty["COUNT3"] || 0) + COUNT3.quantity;
+ if (_.isNumber(VERIFICATION.quantity)) totalQty["VERIFICATION"] = (totalQty["VERIFICATION"] || 0) + VERIFICATION.quantity;
- if (_.isNumber(VERIFICATION.quantity)) verificationCounter++
+ if (_.isNumber(VERIFICATION.quantity)) verificationCounter++;
}
- const product = await prisma.product.findFirst({ where: { id: parseInt(params.productId) } })
- if (!product) return
+ const product = await prisma.product.findFirst({ where: { id: parseInt(params.productId) } });
+ if (!product) return;
- const onhandQty = product.onhandQty
- // const differenceQty = product.differenceQty
- const allQty = totalQty['COUNT1'] + totalQty['COUNT2'] + totalQty['COUNT3'] + totalQty['VERIFICATION']
- const differenceQty = onhandQty - allQty
+ const onhandQty = product.onhandQty;
+ // const differenceQty = product.differenceQty
+ const allQty = totalQty["COUNT1"] + totalQty["COUNT2"] + totalQty["COUNT3"] + totalQty["VERIFICATION"];
+ const differenceQty = onhandQty - allQty;
// const allQty = onhandQty + differenceQty
- const zeroCount1: boolean = totalQty['COUNT1'] === 0;
- const zeroCount2: boolean = totalQty['COUNT2'] === 0;
- const zeroCount3: boolean = totalQty['COUNT3'] === 0;
+ const zeroCount1: boolean = totalQty["COUNT1"] === 0;
+ const zeroCount2: boolean = totalQty["COUNT2"] === 0;
+ const zeroCount3: boolean = totalQty["COUNT3"] === 0;
const conditional = {
verificationCheckAll: verificationCounter > 0 && verificationCounter === stockOpnames.length,
// anyCountEqWithOnhand: [totalQty['COUNT1'], totalQty['COUNT2'], totalQty['COUNT3']].includes(onhandQty),
- anyCountEqWithOnhand: (totalQty['COUNT1'] === onhandQty && zeroCount2 && zeroCount3) || (totalQty['COUNT2'] === onhandQty && zeroCount3) || totalQty['COUNT3'] === onhandQty ,
- anyCountEqWithAllQty: [totalQty['COUNT1'], totalQty['COUNT2'], totalQty['COUNT3']].includes(allQty),
- count1EqWithCount2: totalQty['COUNT1'] !== 0 && totalQty['COUNT2'] !== 0 && totalQty['COUNT1'] === totalQty['COUNT2'] && totalQty['COUNT3'] === null && totalQty['COUNT1'] !== onhandQty,
- count1EqWithCount3: totalQty['COUNT1'] !== 0 && totalQty['COUNT3'] !== 0 && totalQty['COUNT1'] === totalQty['COUNT3'],
- count2EqWithCount3: totalQty['COUNT2'] !== 0 && totalQty['COUNT3'] !== 0 && totalQty['COUNT2'] === totalQty['COUNT3'],
+ // anyCountEqWithOnhand: (totalQty["COUNT1"] === onhandQty && zeroCount2 && zeroCount3) || (totalQty["COUNT2"] === onhandQty && zeroCount3) || totalQty["COUNT3"] === onhandQty,
+ anyCountEqWithOnhand: totalQty["COUNT1"] === onhandQty || totalQty["COUNT2"] === onhandQty || totalQty["COUNT1"] === onhandQty,
+ anyCountEqWithAllQty: [totalQty["COUNT1"], totalQty["COUNT2"], totalQty["COUNT3"]].includes(allQty),
+ count1EqWithCount2: totalQty["COUNT1"] !== 0 && totalQty["COUNT2"] !== 0 && totalQty["COUNT1"] === totalQty["COUNT2"] && totalQty["COUNT3"] === null && totalQty["COUNT1"] !== onhandQty,
+ count1EqWithCount3: totalQty["COUNT1"] !== 0 && totalQty["COUNT3"] !== 0 && totalQty["COUNT1"] === totalQty["COUNT3"],
+ count2EqWithCount3: totalQty["COUNT2"] !== 0 && totalQty["COUNT3"] !== 0 && totalQty["COUNT2"] === totalQty["COUNT3"],
};
-
- // isDifferent = !(
- // conditional.verificationCheckAll ||
- // conditional.anyCountEqWithOnhand ||
- // conditional.anyCountEqWithAllQty ||
- // conditional.count1EqWithCount2 ||
- // conditional.count1EqWithCount3 ||
- // conditional.count2EqWithCount3
- // );
- if (
- conditional.verificationCheckAll ||
- conditional.anyCountEqWithOnhand ||
- conditional.count1EqWithCount2 ||
- conditional.count1EqWithCount3 ||
- conditional.count2EqWithCount3
- ) {
+
+ if (conditional.verificationCheckAll || conditional.anyCountEqWithOnhand || conditional.count1EqWithCount2 || conditional.count1EqWithCount3 || conditional.count2EqWithCount3) {
isDifferent = false;
} else {
isDifferent = true;
@@ -90,49 +76,31 @@ export async function POST(request: NextRequest, { params }: PostParams) {
for (const opname of stockOpnames) {
let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
-
+
const detailCondition = {
verificationCheckAll: _.isNumber(VERIFICATION.quantity),
- anyCountEqWithOnhand: (totalQty['COUNT1'] === onhandQty && zeroCount2 && zeroCount3) || (totalQty['COUNT2'] === onhandQty && zeroCount3) || totalQty['COUNT3'] === onhandQty ,
- count1EqWithCount2: totalQty['COUNT3'] === 0 && COUNT1.quantity === COUNT2.quantity && totalQty['COUNT1'] !== onhandQty,
+ // anyCountEqWithOnhand: (totalQty["COUNT1"] === onhandQty && zeroCount2 && zeroCount3) || (totalQty["COUNT2"] === onhandQty && zeroCount3) || totalQty["COUNT3"] === onhandQty,
+ anyCountEqWithOnhand: totalQty["COUNT1"] === onhandQty || totalQty["COUNT2"] === onhandQty || totalQty["COUNT1"] === onhandQty,
+ count1EqWithCount2: totalQty["COUNT3"] === 0 && COUNT1.quantity === COUNT2.quantity && totalQty["COUNT1"] !== onhandQty,
count1EqWithCount3: COUNT1.quantity === COUNT3.quantity,
- count2EqWithCount3: COUNT2.quantity === COUNT3.quantity && (COUNT2.quantity === 0 && COUNT3.quantity === 0),
+ count2EqWithCount3: COUNT2.quantity === COUNT3.quantity && COUNT2.quantity !== 0 && COUNT3.quantity !== 0,
// count3EqWithCount1_2: (COUNT3.quantity !== COUNT1.quantity) && (COUNT3.quantity !== COUNT2.quantity) && (COUNT1.quantity === COUNT2.quantity) && (COUNT3.quantity !== onhandQty)
};
-
- if (
- detailCondition.verificationCheckAll ||
- detailCondition.anyCountEqWithOnhand ||
- detailCondition.count1EqWithCount2 ||
- detailCondition.count1EqWithCount3 ||
- detailCondition.count2EqWithCount3
- ) {
+
+ if (detailCondition.verificationCheckAll || detailCondition.anyCountEqWithOnhand || detailCondition.count1EqWithCount2 || detailCondition.count1EqWithCount3 || detailCondition.count2EqWithCount3) {
isDifferent = false;
} else {
isDifferent = true;
break;
}
- console.log('----------------------------------BATAS SUCI ATAS RECOMPUTE------------------------------');
- console.log('opname:', opname);
- console.log('Is Different2222:', isDifferent);
- console.log('Conditions:', detailCondition);
}
- console.log('Total Quantity:', totalQty);
- console.log('Onhand Quantity:', onhandQty);
- console.log('Difference Quantity:', differenceQty);
- console.log('Conditions:', conditional);
- console.log('Is Different:', isDifferent);
- console.log('----------------------------------BATAS SUCI BAWAH RECOMPUTE------------------------------');
-
const payload = {
where: { id: product.id },
- data: { isDifferent }
- }
-
- await prisma.product.update(payload)
+ data: { isDifferent },
+ };
- return NextResponse.json(payload)
+ await prisma.product.update(payload);
-
-} \ No newline at end of file
+ return NextResponse.json(payload);
+}
diff --git a/src/app/api/stock-opname/route.tsx b/src/app/api/stock-opname/route.tsx
index 9f44158..1ec79d1 100644
--- a/src/app/api/stock-opname/route.tsx
+++ b/src/app/api/stock-opname/route.tsx
@@ -2,253 +2,212 @@ import { StockOpnameLocationRes, StockOpnameRequest } from "@/common/types/stock
import { Prisma, Team } from "prisma/generated/client";
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "prisma/client";
-import _ from "lodash"
+import _ from "lodash";
import getServerCredential from "@/common/libs/getServerCredential";
type Quantity = {
- [key in keyof typeof Team]: number | null
-}
+ [key in keyof typeof Team]: number | null;
+};
export async function GET(request: NextRequest) {
const PAGE_SIZE = 30;
- const params = request.nextUrl.searchParams
- const companyId = params.get('companyId')
- const search = params.get('search')
- const page = params.get('page') ?? null
- const show = params.get('show')
- const intPage = page ? parseInt(page) : 1
+ const params = request.nextUrl.searchParams;
+ const companyId = params.get("companyId");
+ const search = params.get("search");
+ const page = params.get("page") ?? null;
+ const show = params.get("show");
+ const intPage = page ? parseInt(page) : 1;
if (!companyId) {
- return NextResponse.json({ error: 'Bad Request. Missing companyId' }, { status: 400 })
+ return NextResponse.json({ error: "Bad Request. Missing companyId" }, { status: 400 });
}
const where: Prisma.ProductWhereInput = {
AND: {
stockOpnames: { some: {} },
companyId: parseInt(companyId),
- isDifferent: show ? (show == 'diff' ? true : false) : undefined,
+ isDifferent: show ? (show == "diff" ? true : false) : undefined,
OR: [
- { name: { mode: 'insensitive', contains: search ?? '' } },
- { itemCode: { mode: 'insensitive', contains: search ?? '' } },
- { barcode: { mode: 'insensitive', contains: search ?? '' } },
- { stockOpnames: { some: { location: { name: { mode: 'insensitive', contains: search ?? '' } } } } },
- ]
- }
- }
+ { name: { mode: "insensitive", contains: search ?? "" } },
+ { itemCode: { mode: "insensitive", contains: search ?? "" } },
+ { barcode: { mode: "insensitive", contains: search ?? "" } },
+ { stockOpnames: { some: { location: { name: { mode: "insensitive", contains: search ?? "" } } } } },
+ ],
+ },
+ };
const products = await prisma.product.findMany({
skip: (intPage - 1) * PAGE_SIZE,
take: PAGE_SIZE,
- where
- })
+ where,
+ });
- const productCount = await prisma.product.count({ where })
+ const productCount = await prisma.product.count({ where });
const pagination = {
page: intPage,
totalPage: Math.ceil(productCount / PAGE_SIZE),
- }
+ };
- type ProductWithSum = typeof products[0] & { quantity: Quantity }
+ type ProductWithSum = (typeof products)[0] & { quantity: Quantity };
- const productsWithSum: ProductWithSum[] = []
+ const productsWithSum: ProductWithSum[] = [];
for (const product of products) {
const quantity = await calculateOpnameQuantity({
productId: product.id,
- companyId: parseInt(companyId)
- })
- productsWithSum.push({ ...product, quantity })
+ companyId: parseInt(companyId),
+ });
+ productsWithSum.push({ ...product, quantity });
}
return NextResponse.json({
result: productsWithSum,
- ...pagination
- })
+ ...pagination,
+ });
}
-const calculateOpnameQuantity = async (
- where: {
- productId: number,
- companyId: number
- }
-): Promise<Quantity> => {
- const quantity: Quantity = { COUNT1: null, COUNT2: null, COUNT3: null, VERIFICATION: null }
+const calculateOpnameQuantity = async (where: { productId: number; companyId: number }): Promise<Quantity> => {
+ const quantity: Quantity = { COUNT1: null, COUNT2: null, COUNT3: null, VERIFICATION: null };
for (const team of Object.values(Team)) {
const opnameQty = await prisma.stockOpname.groupBy({
- by: ['productId', 'team'],
+ by: ["productId", "team"],
_sum: { quantity: true },
- where: { team, ...where }
- })
- if (opnameQty.length === 0) continue
- quantity[team] = opnameQty[0]._sum.quantity
+ where: { team, ...where },
+ });
+ if (opnameQty.length === 0) continue;
+ quantity[team] = opnameQty[0]._sum.quantity;
}
- return quantity
-}
+ return quantity;
+};
export async function POST(request: NextRequest) {
- const credential = getServerCredential()
+ const credential = getServerCredential();
- if (!credential) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
+ if (!credential) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
- const body: StockOpnameRequest = await request.json()
+ const body: StockOpnameRequest = await request.json();
- const { companyId, team } = credential
+ const { companyId, team } = credential;
const query = {
locationId: body.location,
productId: body.product,
companyId,
- team
- }
+ team,
+ };
- const stockOpname = await prisma.stockOpname.findFirst({ where: query })
+ const stockOpname = await prisma.stockOpname.findFirst({ where: query });
const data = {
...query,
userId: credential.id,
quantity: body.quantity,
- isDifferent: false
- }
+ isDifferent: false,
+ };
- let newStockOpname = null
+ let newStockOpname = null;
if (!stockOpname) {
- newStockOpname = await prisma.stockOpname.create({ data })
+ newStockOpname = await prisma.stockOpname.create({ data });
} else {
newStockOpname = await prisma.stockOpname.update({
where: { id: stockOpname.id },
- data
- })
+ data,
+ });
}
- await computeIsDifferent({ productId: body.product, companyId: companyId })
+ await computeIsDifferent({ productId: body.product, companyId: companyId });
- return NextResponse.json(newStockOpname)
+ return NextResponse.json(newStockOpname);
}
-const SELF_HOST = process.env.SELF_HOST as string
+const SELF_HOST = process.env.SELF_HOST as string;
-const computeIsDifferent = async ({
- companyId,
- productId
-}: {
- companyId: number,
- productId: number
-}) => {
+const computeIsDifferent = async ({ companyId, productId }: { companyId: number; productId: number }) => {
const totalQty: { [key in keyof typeof Team]: number | 0 } = {
COUNT1: 0,
COUNT2: 0,
COUNT3: 0,
- VERIFICATION: 0
- }
+ VERIFICATION: 0,
+ };
const searchParams = new URLSearchParams({
companyId: companyId.toString(),
- productId: productId.toString()
- })
+ productId: productId.toString(),
+ });
- const stockOpnamesFetch = await fetch(`${SELF_HOST}/api/stock-opname/location?${searchParams}`)
- const stockOpnames: StockOpnameLocationRes[] = await stockOpnamesFetch.json()
+ const stockOpnamesFetch = await fetch(`${SELF_HOST}/api/stock-opname/location?${searchParams}`);
+ const stockOpnames: StockOpnameLocationRes[] = await stockOpnamesFetch.json();
- let isDifferent: boolean = false
- let verificationCounter: number = 0
+ let isDifferent: boolean = false;
+ let verificationCounter: number = 0;
for (const opname of stockOpnames) {
- let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname
+ let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
- if (totalQty['COUNT1'] === null && _.isNumber(COUNT1.quantity)) totalQty['COUNT1'] = 0
- if (totalQty['COUNT2'] === null && _.isNumber(COUNT2.quantity)) totalQty['COUNT2'] = 0
- if (totalQty['COUNT3'] === null && _.isNumber(COUNT3.quantity)) totalQty['COUNT3'] = 0
- if (totalQty['VERIFICATION'] === null && _.isNumber(VERIFICATION.quantity)) totalQty['VERIFICATION'] = 0
+ if (totalQty["COUNT1"] === null && _.isNumber(COUNT1.quantity)) totalQty["COUNT1"] = 0;
+ if (totalQty["COUNT2"] === null && _.isNumber(COUNT2.quantity)) totalQty["COUNT2"] = 0;
+ if (totalQty["COUNT3"] === null && _.isNumber(COUNT3.quantity)) totalQty["COUNT3"] = 0;
+ if (totalQty["VERIFICATION"] === null && _.isNumber(VERIFICATION.quantity)) totalQty["VERIFICATION"] = 0;
- if (_.isNumber(totalQty['COUNT1']) && _.isNumber(COUNT1.quantity)) totalQty['COUNT1'] += COUNT1.quantity
- if (_.isNumber(totalQty['COUNT2']) && _.isNumber(COUNT2.quantity)) totalQty['COUNT2'] += COUNT2.quantity
- if (_.isNumber(totalQty['COUNT3']) && _.isNumber(COUNT3.quantity)) totalQty['COUNT3'] += COUNT3.quantity
- if (_.isNumber(totalQty['VERIFICATION']) && _.isNumber(VERIFICATION.quantity)) totalQty['VERIFICATION'] += VERIFICATION.quantity
+ if (_.isNumber(totalQty["COUNT1"]) && _.isNumber(COUNT1.quantity)) totalQty["COUNT1"] += COUNT1.quantity;
+ if (_.isNumber(totalQty["COUNT2"]) && _.isNumber(COUNT2.quantity)) totalQty["COUNT2"] += COUNT2.quantity;
+ if (_.isNumber(totalQty["COUNT3"]) && _.isNumber(COUNT3.quantity)) totalQty["COUNT3"] += COUNT3.quantity;
+ if (_.isNumber(totalQty["VERIFICATION"]) && _.isNumber(VERIFICATION.quantity)) totalQty["VERIFICATION"] += VERIFICATION.quantity;
- if (_.isNumber(VERIFICATION.quantity)) verificationCounter++
+ if (_.isNumber(VERIFICATION.quantity)) verificationCounter++;
}
- const product = await prisma.product.findFirst({ where: { id: productId } })
- if (!product) return
+ const product = await prisma.product.findFirst({ where: { id: productId } });
+ if (!product) return;
- const onhandQty = product.onhandQty
- const allQty = totalQty['COUNT1'] + totalQty['COUNT2'] + totalQty['COUNT3'] + totalQty['VERIFICATION']
- const differenceQty = onhandQty - allQty
+ const onhandQty = product.onhandQty;
+ const allQty = totalQty["COUNT1"] + totalQty["COUNT2"] + totalQty["COUNT3"] + totalQty["VERIFICATION"];
+ const differenceQty = onhandQty - allQty;
// const differenceQty = product.differenceQty
// const allQty = onhandQty + differenceQty
const conditional = {
verificationCheckAll: verificationCounter > 0 && verificationCounter === stockOpnames.length,
// anyCountEqWithOnhand: [totalQty['COUNT1'], totalQty['COUNT2'], totalQty['COUNT3']].includes(onhandQty),
- anyCountEqWithOnhand: totalQty['COUNT1'] === onhandQty || totalQty['COUNT2'] === onhandQty || totalQty['COUNT1'] === onhandQty ,
- anyCountEqWithAllQty: [totalQty['COUNT1'], totalQty['COUNT2'], totalQty['COUNT3']].includes(allQty),
- count1EqWithCount2: totalQty['COUNT1'] !== null && totalQty['COUNT2'] !== null && totalQty['COUNT1'] === totalQty['COUNT2'] && totalQty['COUNT3'] === null,
- count1EqWithCount3: totalQty['COUNT1'] !== null && totalQty['COUNT3'] !== null && totalQty['COUNT1'] === totalQty['COUNT3'],
- count2EqWithCount3: totalQty['COUNT2'] !== null && totalQty['COUNT3'] !== null && totalQty['COUNT2'] === totalQty['COUNT3'],
- }
-
- // isDifferent = !(
- // conditional.verificationCheckAll ||
- // conditional.anyCountEqWithOnhand ||
- // conditional.anyCountEqWithAllQty ||
- // conditional.count1EqWithCount2 ||
- // conditional.count1EqWithCount3 ||
- // conditional.count2EqWithCount3
- // )
- if (
- conditional.verificationCheckAll ||
- conditional.anyCountEqWithOnhand ||
- conditional.count1EqWithCount2 ||
- conditional.count1EqWithCount3 ||
- conditional.count2EqWithCount3
- ) {
+ anyCountEqWithOnhand: totalQty["COUNT1"] === onhandQty || totalQty["COUNT2"] === onhandQty || totalQty["COUNT1"] === onhandQty,
+ anyCountEqWithAllQty: [totalQty["COUNT1"], totalQty["COUNT2"], totalQty["COUNT3"]].includes(allQty),
+ count1EqWithCount2: totalQty["COUNT1"] !== null && totalQty["COUNT2"] !== null && totalQty["COUNT1"] === totalQty["COUNT2"] && totalQty["COUNT3"] === null,
+ count1EqWithCount3: totalQty["COUNT1"] !== null && totalQty["COUNT3"] !== null && totalQty["COUNT1"] === totalQty["COUNT3"],
+ count2EqWithCount3: totalQty["COUNT2"] !== null && totalQty["COUNT3"] !== null && totalQty["COUNT2"] === totalQty["COUNT3"],
+ };
+
+ if (conditional.verificationCheckAll || conditional.anyCountEqWithOnhand || conditional.count1EqWithCount2 || conditional.count1EqWithCount3 || conditional.count2EqWithCount3) {
isDifferent = false;
} else {
isDifferent = true;
}
for (const opname of stockOpnames) {
- let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname
+ let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
const detailCondition = {
verificationCheckAll: _.isNumber(VERIFICATION.quantity),
- anyCountEqWithOnhand: totalQty['COUNT1'] === onhandQty || totalQty['COUNT2'] === onhandQty || totalQty['COUNT3'] === onhandQty ,
- count1EqWithCount2: totalQty['COUNT3'] === 0 && COUNT1.quantity === COUNT2.quantity,
+ anyCountEqWithOnhand: totalQty["COUNT1"] === onhandQty || totalQty["COUNT2"] === onhandQty || totalQty["COUNT3"] === onhandQty,
+ count1EqWithCount2: totalQty["COUNT3"] === 0 && COUNT1.quantity === COUNT2.quantity,
count1EqWithCount3: COUNT1.quantity === COUNT3.quantity,
- count2EqWithCount3: COUNT2.quantity === COUNT3.quantity && (COUNT2.quantity === 0 && COUNT3.quantity === 0),
+ count2EqWithCount3: COUNT2.quantity === COUNT3.quantity && COUNT2.quantity !== 0 && COUNT3.quantity !== 0,
// count3EqWithCount1_2: (COUNT3.quantity !== COUNT1.quantity) && (COUNT3.quantity !== COUNT2.quantity) && (COUNT1.quantity === COUNT2.quantity) && (COUNT3.quantity !== onhandQty)
- }
+ };
- if (
- detailCondition.verificationCheckAll ||
- detailCondition.anyCountEqWithOnhand ||
- detailCondition.count1EqWithCount2 ||
- detailCondition.count1EqWithCount3 ||
- detailCondition.count2EqWithCount3
- ) {
+ if (detailCondition.verificationCheckAll || detailCondition.anyCountEqWithOnhand || detailCondition.count1EqWithCount2 || detailCondition.count1EqWithCount3 || detailCondition.count2EqWithCount3) {
isDifferent = false;
} else {
isDifferent = true;
break;
}
- console.log('----------------------------------BATAS SUCI ATAS NEW STOCK ------------------------------');
- console.log('Is Different2222:', isDifferent);
- console.log('Conditions:', detailCondition);
}
- console.log('Total Quantity:', totalQty);
- console.log('Onhand Quantity:', onhandQty);
- console.log('Difference Quantity:', differenceQty);
- console.log('Conditions:', conditional);
- console.log('Is Different tambah data:', isDifferent);
- console.log('----------------------------------BATAS SUCI BAWAH NEW STOCK------------------------------');
-
await prisma.product.update({
where: { id: product.id },
- data: { isDifferent }
- })
-} \ No newline at end of file
+ data: { isDifferent },
+ });
+};
diff --git a/src/modules/result/components/Table.tsx b/src/modules/result/components/Table.tsx
index fc40932..19a1e8b 100644
--- a/src/modules/result/components/Table.tsx
+++ b/src/modules/result/components/Table.tsx
@@ -1,9 +1,9 @@
"use client";
import { useResultStore } from "@/common/stores/useResultStore";
import { StockOpnameRes } from "@/common/types/stockOpname";
-import { Button, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Pagination, Skeleton, Spacer, Spinner } from "@nextui-org/react"
+import { Button, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Pagination, Skeleton, Spacer, Spinner } from "@nextui-org/react";
import { keepPreviousData, useQuery } from "@tanstack/react-query";
-import styles from "./table.module.css"
+import styles from "./table.module.css";
import clsxm from "@/common/libs/clsxm";
import DetailRow from "./DetailRow";
import { useDebounce } from "usehooks-ts";
@@ -16,169 +16,173 @@ import toast from "@/common/libs/toast";
import { Product } from "prisma/generated/client";
const Table = () => {
- const credential = getClientCredential()
+ const credential = getClientCredential();
- const { filter: { company, search, show, page }, updateFilter } = useResultStore()
- const debouncedSearch = useDebounce(search, 500)
+ const {
+ filter: { company, search, show, page },
+ updateFilter,
+ } = useResultStore();
+ const debouncedSearch = useDebounce(search, 500);
useEffect(() => {
- updateFilter('page', 1)
- }, [company, debouncedSearch, show, updateFilter])
+ updateFilter("page", 1);
+ }, [company, debouncedSearch, show, updateFilter]);
const stockOpnames = useQuery({
- queryKey: ['stockOpnames', company, debouncedSearch, page, show],
+ queryKey: ["stockOpnames", company, debouncedSearch, page, show],
queryFn: async () => {
- const searchParams = new URLSearchParams()
- if (!company) return null
- searchParams.set('companyId', company)
+ const searchParams = new URLSearchParams();
+ if (!company) return null;
+ searchParams.set("companyId", company);
- const showValue = SHOWING_SELECTIONS.find((item) => item.key === show)?.value || ''
- searchParams.set('show', showValue);
+ const showValue = SHOWING_SELECTIONS.find((item) => item.key === show)?.value || "";
+ searchParams.set("show", showValue);
- if (debouncedSearch) searchParams.set('search', debouncedSearch)
+ if (debouncedSearch) searchParams.set("search", debouncedSearch);
- searchParams.set('page', page.toString());
+ searchParams.set("page", page.toString());
- return await fetch(`/api/stock-opname?${searchParams}`)
- .then(res => {
- window.scrollTo({ top: 0, 'behavior': 'smooth' })
- return res.json()
- })
+ return await fetch(`/api/stock-opname?${searchParams}`).then((res) => {
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ return res.json();
+ });
},
- placeholderData: keepPreviousData
- })
+ placeholderData: keepPreviousData,
+ });
- const { filter } = useResultStore()
+ const { filter } = useResultStore();
- const [exportLoad, setExportLoad] = useState<boolean>(false)
+ const [exportLoad, setExportLoad] = useState<boolean>(false);
const exportResult = async () => {
- setExportLoad(true)
- const response = await fetch(`/api/stock-opname/export?companyId=${filter.company}`)
- const buffer = await response.arrayBuffer()
- console.log({ type: response.headers.get('type') });
-
- const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
- const url = window.URL.createObjectURL(blob)
- const a = document.createElement('a')
- a.href = url
- a.download = `export_${moment().format('MM_DD_HH_ss')}.xlsx`
- document.body.appendChild(a)
- a.click()
- document.body.removeChild(a)
- setExportLoad(false)
- }
+ setExportLoad(true);
+ const response = await fetch(`/api/stock-opname/export?companyId=${filter.company}`);
+ const buffer = await response.arrayBuffer();
+ console.log({ type: response.headers.get("type") });
+
+ const blob = new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
+ const url = window.URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = `export_${moment().format("MM_DD_HH_ss")}.xlsx`;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ setExportLoad(false);
+ };
const toggleDifferent = async (id: number) => {
- const response = await fetch(`/api/product/${id}/toggle-different`, { method: 'POST' })
- const product: Product = await response.json()
- toast(`Berhasil mengubah status barang ${product.itemCode} ${product.name} menjadi ${product.isDifferent ? 'selisih' : 'aman'}`, { duration: 10000 })
- stockOpnames.refetch()
- }
+ const response = await fetch(`/api/product/${id}/toggle-different`, { method: "POST" });
+ const product: Product = await response.json();
+ toast(`Berhasil mengubah status barang ${product.itemCode} ${product.name} menjadi ${product.isDifferent ? "selisih" : "aman"}`, { duration: 10000 });
+ stockOpnames.refetch();
+ };
const recompute = async (productId: number, companyId: string) => {
- const response = await fetch(`/api/company/${companyId}/product/${productId}/compute-different`, { method: 'POST' })
- console.log("response",response)
- const stockOpname = await response.json()
- console.log("stockOpname",stockOpname)
- toast(`Berhasil menghitung ulang status barang, hasilnya ${stockOpname.data.isDifferent ? 'selisih' : 'aman'}`)
- stockOpnames.refetch()
- }
+ const response = await fetch(`/api/company/${companyId}/product/${productId}/compute-different`, { method: "POST" });
+ console.log("response", response);
+ const stockOpname = await response.json();
+ console.log("stockOpname", stockOpname);
+ toast(`Berhasil menghitung ulang status barang, hasilnya ${stockOpname.data.isDifferent ? "selisih" : "aman"}`);
+ stockOpnames.refetch();
+ };
- const isLoading = stockOpnames.isLoading || stockOpnames.isRefetching
+ const isLoading = stockOpnames.isLoading || stockOpnames.isRefetching;
- const COL_LENGTH = 9
+ const COL_LENGTH = 9;
return (
<>
<div className="flex">
<Button type="button" onPress={exportResult} disabled={exportLoad} variant="flat" className="ml-auto mb-4">
- {exportLoad ? <><Spinner size="sm" />Exporting...</> : 'Export'}
+ {exportLoad ? (
+ <>
+ <Spinner size="sm" />
+ Exporting...
+ </>
+ ) : (
+ "Export"
+ )}
</Button>
</div>
<div className="w-full flex-1 overflow-auto pb-4">
<table className="w-full">
- <thead className={styles.thead}>
- <tr>
- <th className={styles.th}>STATUS</th>
- <th className={clsxm(styles.th, '!text-left')}>NAMA PRODUK</th>
- <th className={styles.th}>TIM HITUNG 1</th>
- <th className={styles.th}>TIM HITUNG 2</th>
- <th className={styles.th}>TIM HITUNG 3</th>
- <th className={styles.th}>TIM VERIFIKASI</th>
- <th className={styles.th}>ON-HAND QTY</th>
- <th className={styles.th}>GUDANG SELISIH</th>
- <th className={styles.th}></th>
- </tr>
- </thead>
+ <thead className={styles.thead}>
+ <tr>
+ <th className={styles.th}>STATUS</th>
+ <th className={clsxm(styles.th, "!text-left")}>NAMA PRODUK</th>
+ <th className={styles.th}>TIM HITUNG 1</th>
+ <th className={styles.th}>TIM HITUNG 2</th>
+ <th className={styles.th}>TIM HITUNG 3</th>
+ <th className={styles.th}>TIM VERIFIKASI</th>
+ <th className={styles.th}>ON-HAND QTY</th>
+ <th className={styles.th}>GUDANG SELISIH</th>
+ <th className={styles.th}></th>
+ </tr>
+ </thead>
<tbody className={styles.tbody}>
- {!isLoading && stockOpnames.data?.result.map((stockOpname: StockOpnameRes['result']) => (
- <>
- <tr key={stockOpname.id} className={clsxm("border-t border-neutral-200", {
- "text-danger-600": stockOpname.isDifferent,
- "text-success-600": !stockOpname.isDifferent
- })}
- >
- <td className={styles.td}>
- <div className={clsxm("w-full rounded-lg mr-1 p-1 text-xs text-white whitespace-nowrap", {
- "bg-danger-600": stockOpname.isDifferent,
- "bg-success-600": !stockOpname.isDifferent,
- })}>
- {stockOpname.isDifferent ? 'Selisih' : 'Aman'}
- </div>
- </td>
- <td className={clsxm(styles.td, '!text-left flex min-w-[250px]')} aria-label="name">
- {stockOpname.itemCode ? `[${stockOpname.itemCode}] ` : ''}
- {stockOpname.name}
- {stockOpname.barcode ? ` [${stockOpname.barcode}]` : ''}
- </td>
- <td className={styles.td}>
- {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.COUNT1 === 'number' ? stockOpname.quantity.COUNT1 : '-'}
- </td>
- <td className={styles.td}>
- {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.COUNT2 === 'number' ? stockOpname.quantity.COUNT2 : '-'}
- </td>
- <td className={styles.td}>
- {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.COUNT3 === 'number' ? stockOpname.quantity.COUNT3 : '-'}
- </td>
- <td className={styles.td}>
- {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.VERIFICATION === 'number' ? stockOpname.quantity.VERIFICATION : '-'}
- </td>
- <td className={styles.td}>
- {credential?.team == 'VERIFICATION' ? stockOpname.onhandQty : '-'}
- </td>
- <td className={styles.td}>
- {credential?.team == 'VERIFICATION' ? stockOpname.differenceQty : '-'}
- </td>
- <td>
- {credential?.team == 'VERIFICATION' && (
- <Dropdown>
- <DropdownTrigger>
- <Button variant="light" className="p-1 min-w-fit">
- <MoreVerticalIcon size={16} />
- </Button>
- </DropdownTrigger>
- <DropdownMenu>
- <DropdownItem key="recompute" onPress={() => recompute(stockOpname.id, company)}>
- Re-compute
- </DropdownItem>
- <DropdownItem key="toggleDifferent" onPress={() => toggleDifferent(stockOpname.id)}>
- Tandai {stockOpname.isDifferent ? 'aman' : 'selisih'}
- </DropdownItem>
- </DropdownMenu>
- </Dropdown>
- )}
- </td>
- </tr>
-
- <DetailRow productId={stockOpname.id} />
- </>
- ))}
+ {!isLoading &&
+ stockOpnames.data?.result.map((stockOpname: StockOpnameRes["result"]) => (
+ <>
+ <tr
+ key={stockOpname.id}
+ className={clsxm("border-t border-neutral-200", {
+ "text-danger-600": stockOpname.isDifferent,
+ "text-success-600": !stockOpname.isDifferent,
+ })}
+ >
+ <td className={styles.td}>
+ <div
+ className={clsxm("w-full rounded-lg mr-1 p-1 text-xs text-white whitespace-nowrap", {
+ "bg-danger-600": stockOpname.isDifferent,
+ "bg-success-600": !stockOpname.isDifferent,
+ })}
+ >
+ {stockOpname.isDifferent ? "Selisih" : "Aman"}
+ </div>
+ </td>
+ <td className={clsxm(styles.td, "!text-left flex min-w-[250px]")} aria-label="name">
+ {stockOpname.itemCode ? `[${stockOpname.itemCode}] ` : ""}
+ {stockOpname.name}
+ {stockOpname.barcode ? ` [${stockOpname.barcode}]` : ""}
+ </td>
+ <td className={styles.td}>{credential?.team == "VERIFICATION" && typeof stockOpname.quantity.COUNT1 === "number" ? stockOpname.quantity.COUNT1 : "-"}</td>
+ <td className={styles.td}>{credential?.team == "VERIFICATION" && typeof stockOpname.quantity.COUNT2 === "number" ? stockOpname.quantity.COUNT2 : "-"}</td>
+ <td className={styles.td}>{credential?.team == "VERIFICATION" && typeof stockOpname.quantity.COUNT3 === "number" ? stockOpname.quantity.COUNT3 : "-"}</td>
+ <td className={styles.td}>{credential?.team == "VERIFICATION" && typeof stockOpname.quantity.VERIFICATION === "number" ? stockOpname.quantity.VERIFICATION : "-"}</td>
+ <td className={styles.td}>{credential?.team == "VERIFICATION" ? stockOpname.onhandQty : "-"}</td>
+ <td className={styles.td}>{credential?.team == "VERIFICATION" ? stockOpname.differenceQty : "-"}</td>
+ <td>
+ {credential?.team == "VERIFICATION" && (
+ <Dropdown>
+ <DropdownTrigger>
+ <Button variant="light" className="p-1 min-w-fit">
+ <MoreVerticalIcon size={16} />
+ </Button>
+ </DropdownTrigger>
+ <DropdownMenu>
+ <DropdownItem key="recompute" onPress={() => recompute(stockOpname.id, company)}>
+ Re-compute
+ </DropdownItem>
+ <DropdownItem key="toggleDifferent" onPress={() => toggleDifferent(stockOpname.id)}>
+ Tandai {stockOpname.isDifferent ? "aman" : "selisih"}
+ </DropdownItem>
+ </DropdownMenu>
+ </Dropdown>
+ )}
+ </td>
+ </tr>
+
+ <DetailRow productId={stockOpname.id} />
+ </>
+ ))}
{!isLoading && stockOpnames.data?.result.length === 0 && (
<tr>
- <td colSpan={COL_LENGTH} className="text-center text-neutral-600 py-4">Belum ada data untuk ditampilkan</td>
+ <td colSpan={COL_LENGTH} className="text-center text-neutral-600 py-4">
+ Belum ada data untuk ditampilkan
+ </td>
</tr>
)}
@@ -195,19 +199,13 @@ const Table = () => {
)}
</tbody>
</table>
-
</div>
<Spacer y={4} />
- <Pagination
- page={stockOpnames.data?.page || 1}
- total={stockOpnames.data?.totalPage || 1}
- onChange={(page) => updateFilter('page', page)}
- className="min-h-[36px] m-0 p-0"
- />
+ <Pagination page={stockOpnames.data?.page || 1} total={stockOpnames.data?.totalPage || 1} onChange={(page) => updateFilter("page", page)} className="min-h-[36px] m-0 p-0" />
</>
- )
-}
+ );
+};
-export default Table \ No newline at end of file
+export default Table;