fix: fixed warehouse inventory numbers and some button verbage

This commit is contained in:
2026-04-21 04:38:07 +00:00
parent c94de8198f
commit 5194d0e21e
29 changed files with 835 additions and 575 deletions
+1
View File
@@ -11,6 +11,7 @@ export { catalogCategoryTranslation } from "./translations/catalog-category";
export { catalogSubcategoryTranslation } from "./translations/catalog-subcategory";
export { catalogManufacturerTranslation } from "./translations/catalog-manufacturer";
export { warehouseBinTranslation } from "./translations/warehouse-bin";
export { warehouseTranslation } from "./translations/warehouse";
export { productInventoryTranslation } from "./translations/product-inventory";
export { productDataTranslation } from "./translations/product-data.ts";
export { corporateLocationTranslation } from "./translations/corporate-location";
+13
View File
@@ -45,6 +45,7 @@ import {
activityNotesTranslation,
userTranslation,
warehouseBinTranslation,
warehouseTranslation,
type TranslationContext,
} from "./index";
import { Translation, SkipRowError } from "./translations/types";
@@ -693,6 +694,13 @@ const getConfigForTable = (table: string): SyncTableConfig | null => {
uniqueField: "id",
lastUpdatedField: "lastUpdatedUtc",
},
warehouse: {
sourceModel: "warehouse",
targetModel: "warehouse",
translation: warehouseTranslation as unknown as AnyTranslation,
uniqueField: "id",
lastUpdatedField: "lastUpdatedUtc",
},
warehouseBin: {
sourceModel: "warehouseBin",
targetModel: "warehouseBin",
@@ -800,6 +808,11 @@ const getConfigForTable = (table: string): SyncTableConfig | null => {
closedFlag: true,
},
},
soInterest: {
select: {
description: true,
},
},
},
},
},
+42
View File
@@ -51,6 +51,7 @@ import {
cwMemberTypeTranslation,
userTranslation,
warehouseBinTranslation,
warehouseTranslation,
type TranslationContext,
} from "./index";
import { Translation, SkipRowError } from "./translations/types";
@@ -1669,6 +1670,15 @@ export const executeFullDalpuriSync = async (options?: {
sourceIdField: "manufacturerRecId",
sourceUpdatedField: "lastUpdatedUtc",
},
{
name: "Warehouses",
sourceModel: "warehouse",
targetModel: "warehouse",
translation: warehouseTranslation as unknown as AnyTranslation,
uniqueField: "id",
sourceIdField: "warehouseRecId",
sourceUpdatedField: "lastUpdatedUtc",
},
{
name: "Warehouse Bins",
sourceModel: "warehouseBin",
@@ -1827,6 +1837,11 @@ export const executeFullDalpuriSync = async (options?: {
closedFlag: true,
},
},
soInterest: {
select: {
description: true,
},
},
},
},
},
@@ -2112,6 +2127,33 @@ export const executeFullDalpuriSync = async (options?: {
`${step.name}: upserted=${result.insertedOrUpdated} skipped=${result.skipped} failed=${result.failed}`
);
// After syncing product inventory, recalculate CatalogItem.onHand for all items
// by summing all ProductInventory.qtyOnHand rows grouped by itemId.
if (step.targetModel === "productInventory") {
console.log(" [post-step] Recalculating CatalogItem.onHand from ProductInventory...");
const grouped = await apiPrisma.productInventory.groupBy({
by: ["itemId"],
_sum: { qtyOnHand: true },
where: { itemId: { not: null } },
});
for (const group of grouped) {
if (group.itemId == null) continue;
await apiPrisma.catalogItem.updateMany({
where: { id: group.itemId },
data: { onHand: group._sum.qtyOnHand ?? 0 },
});
}
// Zero out items that have no inventory rows
const itemIdsWithInventory = grouped
.map((g) => g.itemId)
.filter((id): id is number => id != null);
await apiPrisma.catalogItem.updateMany({
where: { id: { notIn: itemIdsWithInventory } },
data: { onHand: 0 },
});
console.log(` [post-step] Updated onHand for ${grouped.length} catalog items.`);
}
await writeStepLog(
step.name,
effectiveDecision.mode,
-5
View File
@@ -45,11 +45,6 @@ export const catalogItemTranslation: Translation<
},
{ from: "inactiveFlag", to: "inactive" },
{ from: "taxableFlag", to: "salesTaxable" },
{
from: "minimumStock",
to: "onHand",
process: (value) => (value == null ? 0 : value),
},
{ from: "classId", to: "classId" },
{ from: "dateEnteredUtc", to: "createdAt" },
{ from: "lastUpdatedUtc", to: "cwLastUpdated" },
+11 -5
View File
@@ -45,13 +45,19 @@ type CwOpportunityWithMembers = CwOpportunity & {
"memberRecId" | "primarySalesFlag" | "secondarySalesFlag"
>[];
soOppStatus?: Pick<CwSoOppStatus, "closedFlag"> | null;
soInterest?: { description: string | null } | null;
};
const toInterest = (value: number | null): OpportunityInterest | null => {
const toInterest = (
value: { description: string | null } | null
): OpportunityInterest | null => {
if (value == null) return null;
if (value <= 1) return OpportunityInterest.COLD;
if (value === 2) return OpportunityInterest.WARM;
return OpportunityInterest.HOT;
const desc = value.description?.toLowerCase() ?? "";
if (desc.includes("cold")) return OpportunityInterest.COLD;
if (desc.includes("warm") || desc.includes("medium"))
return OpportunityInterest.WARM;
if (desc.includes("hot")) return OpportunityInterest.HOT;
return null;
};
export const opportunityTranslation: Translation<
@@ -85,7 +91,7 @@ export const opportunityTranslation: Translation<
{ from: "soOppStatusRecId", to: "statusId" },
{ from: "taxCodeRecId", to: "taxCodeId" },
{
from: "soInterestRecId",
from: "soInterest",
to: "interest",
process: toInterest,
},
@@ -18,6 +18,7 @@ export const productInventoryTranslation: Translation<
to: "createdAt",
process: (value) => (value ? value : new Date(0)),
},
{ from: "warehouseRecId", to: "warehouseId" },
{ from: "warehouseBinRecId", to: "warehouseBinId" },
{ from: "catalogRecId", to: "itemId" },
{ from: "updatedBy", to: "updatedById" },
@@ -34,6 +34,7 @@ export const warehouseBinTranslation: Translation<
to: "defaultFlag",
process: (value) => Boolean(value),
},
{ from: "warehouseRecId", to: "warehouseId" },
{ from: "updatedBy", to: "updatedById" },
{ from: "enteredBy", to: "createdById" },
{ from: "lastUpdatedUtc", to: "updatedAt" },
+28
View File
@@ -0,0 +1,28 @@
import { Warehouse as CwWarehouse } from "../../generated/prisma/client";
import { Warehouse as ApiWarehouse } from "../../../api/generated/prisma/client";
import { Translation } from "./types";
export const warehouseTranslation: Translation<CwWarehouse, ApiWarehouse> = {
values: [
{ from: "warehouseRecId", to: "id" },
{
from: "warehouseName",
to: "name",
process: (value) => (value ? value : "Unnamed Warehouse"),
},
{
from: "inactiveFlag",
to: "inactiveFlag",
process: (value) => Boolean(value),
},
{
from: "lockedFlag",
to: "lockedFlag",
process: (value) => Boolean(value),
},
{ from: "updatedBy", to: "updatedById" },
{ from: "enteredBy", to: "createdById" },
{ from: "lastUpdatedUtc", to: "updatedAt" },
{ from: "dateEnteredUtc", to: "createdAt" },
],
};