From 4920cb70da33d4d22ebc71617f8e2dc680988b10 Mon Sep 17 00:00:00 2001 From: SandipBajracharya Date: Wed, 4 Mar 2026 15:34:58 +0545 Subject: [PATCH 1/3] fix(OUT-3244): add missing portalid condition while product map update --- src/app/api/quickbooks/product/product.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/api/quickbooks/product/product.service.ts b/src/app/api/quickbooks/product/product.service.ts index ecdde92..6fd8a85 100644 --- a/src/app/api/quickbooks/product/product.service.ts +++ b/src/app/api/quickbooks/product/product.service.ts @@ -266,7 +266,7 @@ export class ProductService extends BaseService { const query = this.db .update(QBProductSync) .set(parsedInsertPayload) - .where(conditions) + .where(and(conditions, eq(QBProductSync.portalId, this.user.workspaceId))) const [product] = returningFields?.length ? await query.returning( @@ -707,7 +707,7 @@ export class ProductService extends BaseService { console.info( `ProductService#updateProductSyncToken. Item not found for Id ${qbItemId} in QuickBooks. Unmapping the product...`, ) - await this.unmapProducts(qbItemId) + if (updateMappingTable) await this.unmapProducts(qbItemId) return } else if (!item.Active) { console.info( From fd493b1c5743bbf61b7995a316a1b080bb54c5b6 Mon Sep 17 00:00:00 2001 From: SandipBajracharya Date: Wed, 4 Mar 2026 15:41:45 +0545 Subject: [PATCH 2/3] fix(OUT-3244): silent return if item not found in QB --- src/app/api/quickbooks/product/product.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/quickbooks/product/product.service.ts b/src/app/api/quickbooks/product/product.service.ts index 6fd8a85..67e58b8 100644 --- a/src/app/api/quickbooks/product/product.service.ts +++ b/src/app/api/quickbooks/product/product.service.ts @@ -707,7 +707,7 @@ export class ProductService extends BaseService { console.info( `ProductService#updateProductSyncToken. Item not found for Id ${qbItemId} in QuickBooks. Unmapping the product...`, ) - if (updateMappingTable) await this.unmapProducts(qbItemId) + // if (updateMappingTable) await this.unmapProducts(qbItemId) return } else if (!item.Active) { console.info( From ea36866759a4f84b50c2c1cefce8cd1b91114f3c Mon Sep 17 00:00:00 2001 From: SandipBajracharya Date: Wed, 4 Mar 2026 18:52:18 +0545 Subject: [PATCH 3/3] fix(OUT-3244): apply fixes to resolve product update related issues - [x] display item name from QBO rather than from mapping table - [x] exclude unmapped items from updating - [x] resolve bug that allows to map same product with multiple prices --- .../api/quickbooks/product/product.service.ts | 2 ++ .../sections/product/ProductMappingTable.tsx | 11 +++++++- src/hook/useSettings.ts | 27 ++++++++++++++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/app/api/quickbooks/product/product.service.ts b/src/app/api/quickbooks/product/product.service.ts index 67e58b8..09af0e0 100644 --- a/src/app/api/quickbooks/product/product.service.ts +++ b/src/app/api/quickbooks/product/product.service.ts @@ -397,6 +397,8 @@ export class ProductService extends BaseService { let itemCount = 0 for (const product of mappedProducts) { + if (product.isExcluded) continue + const qbItemId = z.string().parse(product.qbItemId) const productId = z.string().parse(product.productId) diff --git a/src/components/dashboard/settings/sections/product/ProductMappingTable.tsx b/src/components/dashboard/settings/sections/product/ProductMappingTable.tsx index 3dbe986..941c6c4 100644 --- a/src/components/dashboard/settings/sections/product/ProductMappingTable.tsx +++ b/src/components/dashboard/settings/sections/product/ProductMappingTable.tsx @@ -4,6 +4,7 @@ import useClickOutside from '@/hook/useClickOutside' import { useDropdownPosition } from '@/hook/useDropdown' import { ProductDataType, + QBItemDataType, useMapItem, useProductTableSetting, } from '@/hook/useSettings' @@ -14,12 +15,19 @@ const MapItemComponent = ({ mappingItems, productId, priceId, + qbItems, }: { mappingItems: ProductMappingItemType[] | undefined productId: string priceId: string + qbItems: QBItemDataType[] | undefined }) => { - const { currentlyMapped } = useMapItem(mappingItems, productId, priceId) + const { currentlyMapped } = useMapItem( + mappingItems, + productId, + priceId, + qbItems, + ) return ( <> {currentlyMapped ? ( @@ -148,6 +156,7 @@ export default function ProductMappingTable({ mappingItems={mappingItems} productId={product.id} priceId={product.priceId} + qbItems={quickbooksItems} /> )} diff --git a/src/hook/useSettings.ts b/src/hook/useSettings.ts index 1b8ea0a..d0f6dd9 100644 --- a/src/hook/useSettings.ts +++ b/src/hook/useSettings.ts @@ -203,7 +203,11 @@ export const useProductMappingSettings = () => { [index]: '', })) const fileteredChangedItem = changedItemReference.filter( - (item) => item.id !== products[index].id, + (item) => + !( + item.id === products[index].id && + item.priceId === products[index].priceId + ), ) const newVal = [ ...fileteredChangedItem, @@ -448,6 +452,7 @@ export const useMapItem = ( mappingItems: ProductMappingItemType[] | undefined, productId: string, priceId: string, + qbItems: QBItemDataType[] | undefined, ) => { const [currentlyMapped, setCurrentlyMapped] = useState< ProductMappingItemType | undefined @@ -460,8 +465,24 @@ export const useMapItem = ( item.qbItemId ) }) - setCurrentlyMapped(currentMapItem) - return currentMapItem + const currentQbItem = qbItems?.find((item) => { + return item.id === currentMapItem?.qbItemId + }) + + let itemToReturn: { name: string; unitPrice: string } | undefined + const itemName = currentQbItem?.name || currentMapItem?.name + const itemUnitPrice = + currentQbItem?.numericPrice.toFixed(2) || currentMapItem?.unitPrice + + if (itemName && itemUnitPrice) { + itemToReturn = { + name: itemName, + unitPrice: itemUnitPrice, + } + } + + setCurrentlyMapped(itemToReturn) + return itemToReturn } useEffect(() => {