From d131b3cc79148b9f72a9bfe2fab3a0c6b3dd092d Mon Sep 17 00:00:00 2001
From: Mqdd <ahmadmiqdad27@gmail.com>
Date: Thu, 12 Feb 2026 10:25:19 +0700
Subject: <Miqdad> fix logic

---
 src/app/api/stock-opname/route.tsx | 158 ++++++++++++++++++-------------------
 1 file changed, 79 insertions(+), 79 deletions(-)

(limited to 'src/app/api/stock-opname/route.tsx')

diff --git a/src/app/api/stock-opname/route.tsx b/src/app/api/stock-opname/route.tsx
index 8e09351..e202d4d 100644
--- a/src/app/api/stock-opname/route.tsx
+++ b/src/app/api/stock-opname/route.tsx
@@ -1,4 +1,7 @@
-import { StockOpnameLocationRes, StockOpnameRequest } from "@/common/types/stockOpname";
+import {
+  StockOpnameLocationRes,
+  StockOpnameRequest,
+} from "@/common/types/stockOpname";
 import { Prisma, Team } from "prisma/generated/client";
 import { NextRequest, NextResponse } from "next/server";
 import { prisma } from "prisma/client";
@@ -20,7 +23,10 @@ export async function GET(request: NextRequest) {
   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 = {
@@ -32,7 +38,15 @@ export async function GET(request: NextRequest) {
         { name: { mode: "insensitive", contains: search ?? "" } },
         { itemCode: { mode: "insensitive", contains: search ?? "" } },
         { barcode: { mode: "insensitive", contains: search ?? "" } },
-        { stockOpnames: { some: { location: { name: { mode: "insensitive", contains: search ?? "" } } } } },
+        {
+          stockOpnames: {
+            some: {
+              location: {
+                name: { mode: "insensitive", contains: search ?? "" },
+              },
+            },
+          },
+        },
       ],
     },
   };
@@ -68,8 +82,16 @@ export async function GET(request: NextRequest) {
   });
 }
 
-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({
@@ -86,7 +108,8 @@ const calculateOpnameQuantity = async (where: { productId: number; companyId: nu
 export async function POST(request: NextRequest) {
   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();
 
@@ -126,12 +149,18 @@ export async function POST(request: NextRequest) {
 
 const SELF_HOST = process.env.SELF_HOST as string;
 
-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,
+const computeIsDifferent = async ({
+  companyId,
+  productId,
+}: {
+  companyId: number;
+  productId: number;
+}) => {
+  const totalQty: { [key in keyof typeof Team]: number | null } = {
+    COUNT1: null,
+    COUNT2: null,
+    COUNT3: null,
+    VERIFICATION: null,
   };
 
   const searchParams = new URLSearchParams({
@@ -139,89 +168,60 @@ const computeIsDifferent = async ({ companyId, productId }: { companyId: number;
     productId: productId.toString(),
   });
 
-  const stockOpnamesFetch = await fetch(`${SELF_HOST}/api/stock-opname/location?${searchParams}`);
+  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 verificationExists = false;
 
   for (const opname of stockOpnames) {
-    let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
+    const { 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;
+    const teams = { COUNT1, COUNT2, COUNT3, VERIFICATION };
 
-    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;
+    for (const key of Object.keys(teams) as (keyof typeof teams)[]) {
+      const qty = teams[key]?.quantity;
 
-    if (_.isNumber(VERIFICATION.quantity)) verificationCounter++;
+      if (_.isNumber(qty)) {
+        totalQty[key] = (totalQty[key] ?? 0) + qty;
+
+        if (key === "VERIFICATION") {
+          verificationExists = true;
+        }
+      }
+    }
   }
 
-  const product = await prisma.product.findFirst({ where: { id: productId } });
+  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 differenceQty = product.differenceQty
-  // const allQty = onhandQty + differenceQty
 
-  const zeroCount1: boolean = totalQty["COUNT1"] === 0;
-  const zeroCount2: boolean = totalQty["COUNT2"] === 0;
-  const zeroCount3: boolean = totalQty["COUNT3"] === 0;
+  let isDifferent = true;
 
-  // Jika ada verifikasi qty, langsung AMAN
-  if (verificationCounter > 0) {
-    isDifferent = false;
-  } else {
-    // Jika tidak ada qty verifikasi, cek kondisi tim 1/2/3
-    const conditional = {
-      // 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"] !== 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"] !== 0 && totalQty["COUNT3"] !== 0 && totalQty["COUNT2"] === totalQty["COUNT3"],
-    };
-
-    if (conditional.anyCountEqWithOnhand || conditional.count1EqWithCount2 || conditional.count1EqWithCount3 || conditional.count2EqWithCount3) {
-      isDifferent = false;
-    } 
-    else {
-      isDifferent = true;
-    }
-  }
+  const countValues = [
+    totalQty.COUNT1,
+    totalQty.COUNT2,
+    totalQty.COUNT3,
+  ].filter((v): v is number => v !== null);
 
-  for (const opname of stockOpnames) {
-    let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
-
-    // Normalize: treat missing (null/undefined) same as 0
-    const count1 = _.isNumber(COUNT1.quantity) ? COUNT1.quantity : 0;
-    const count2 = _.isNumber(COUNT2.quantity) ? COUNT2.quantity : 0;
-    const count3 = _.isNumber(COUNT3.quantity) ? COUNT3.quantity : 0;
-
-    const detailCondition = {
-      verificationCheckAll: _.isNumber(VERIFICATION.quantity),
-      anyCountEqWithOnhand: (totalQty["COUNT1"] === onhandQty && zeroCount2 && zeroCount3) || (totalQty["COUNT2"] === onhandQty && zeroCount3) || (totalQty["COUNT3"] === onhandQty),
-      count1EqWithCount2: totalQty["COUNT3"] === 0 && count1 === count2,
-      // count1EqWithCount3: count1 === count3,
-      count1EqWithCount3: count1 != 0 && count1 === count3,
-      count2EqWithCount3: totalQty["COUNT2"] !== 0 && totalQty["COUNT3"] !== 0 && count2 === count3,
-      // 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) {
-      isDifferent = false;
-    }
-    else {
-      isDifferent = true;
-      break;
-    }
+  const uniqueCounts = [...new Set(countValues)];
 
+  if (verificationExists) {
+    isDifferent = false;
+  } else if (onhandQty === 0 && countValues.includes(0)) {
+    isDifferent = false;
+  } else if (countValues.length === 1) {
+    isDifferent = countValues[0] !== onhandQty;
+  } else if (uniqueCounts.length === 1) {
+    isDifferent = uniqueCounts[0] !== onhandQty;
+  } else {
+    isDifferent = true;
   }
 
   await prisma.product.update({
-- 
cgit v1.2.3

