From 1d625b8b7ea72164aaf1f315ba896486e58b4826 Mon Sep 17 00:00:00 2001 From: SandipBajracharya Date: Mon, 26 Jan 2026 17:04:38 +0545 Subject: [PATCH] fix(OUT-2974): fetch item from QBO before creating and map if exists - [x] before creating item in QBO, fetching if the item with same name exists - [x] if item exists, map them in our db - [x] if doesn't exist, create new item in QBO --- .../api/quickbooks/product/product.service.ts | 60 +++++++++++-------- src/app/api/quickbooks/sync/sync.service.ts | 2 +- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/app/api/quickbooks/product/product.service.ts b/src/app/api/quickbooks/product/product.service.ts index 1633d64..ecdde92 100644 --- a/src/app/api/quickbooks/product/product.service.ts +++ b/src/app/api/quickbooks/product/product.service.ts @@ -548,23 +548,28 @@ export class ProductService extends BaseService { ) const productDescription = convert(copilotProduct.description) - const tokenService = new TokenService(this.user) - const incomeAccountRef = await tokenService.checkAndUpdateAccountStatus( - AccountTypeObj.Income, - qbTokenInfo.intuitRealmId, - intuitApi, - qbTokenInfo.incomeAccountRef, - ) - // create item in QB - const item = await this.createItemInQB( - { - productName: z.string().parse(qbItemName), - unitPrice: priceResource.amount, - incomeAccRefVal: z.string().parse(incomeAccountRef), - productDescription, - }, - intuitApi, - ) + // check if item with name exists in QBO + let qbItem = await intuitApi.getAnItem(qbItemName, undefined, true) + + if (!qbItem) { + const tokenService = new TokenService(this.user) + const incomeAccountRef = await tokenService.checkAndUpdateAccountStatus( + AccountTypeObj.Income, + qbTokenInfo.intuitRealmId, + intuitApi, + qbTokenInfo.incomeAccountRef, + ) + // create item in QB + qbItem = await this.createItemInQB( + { + productName: z.string().parse(qbItemName), + unitPrice: priceResource.amount, + incomeAccRefVal: z.string().parse(incomeAccountRef), + productDescription, + }, + intuitApi, + ) + } // map product and price await this.createQBProduct({ @@ -572,20 +577,25 @@ export class ProductService extends BaseService { productId: priceResource.productId, priceId: priceResource.id, unitPrice: priceResource.amount.toFixed(2), - qbItemId: item.Id, - qbSyncToken: item.SyncToken, + qbItemId: qbItem.Id, + qbSyncToken: qbItem.SyncToken, name: qbItemName, copilotName: copilotProduct.name, description: productDescription, }) console.info('WebhookService#webhookPriceCreated | Product created in QB') - await this.logSync(priceResource.productId, item.Id, EventType.CREATED, { - productName: copilotProduct.name, - productPrice: priceResource.amount.toFixed(2), - qbItemName: item.Name, - copilotPriceId: priceResource.id, - }) + await this.logSync( + priceResource.productId, + qbItem.Id, + EventType.CREATED, + { + productName: copilotProduct.name, + productPrice: priceResource.amount.toFixed(2), + qbItemName: qbItem.Name, + copilotPriceId: priceResource.id, + }, + ) this.unsetTransaction() }) diff --git a/src/app/api/quickbooks/sync/sync.service.ts b/src/app/api/quickbooks/sync/sync.service.ts index 515a71d..43dc2c8 100644 --- a/src/app/api/quickbooks/sync/sync.service.ts +++ b/src/app/api/quickbooks/sync/sync.service.ts @@ -522,7 +522,7 @@ export class SyncService extends BaseService { // report to sentry if any records has exceeded max retry count if (attempt == MAX_ATTEMPTS) { captureMessage( - `SyncService#intiateSync | Records exceeded max retry count. Portal Id: ${this.user.workspaceId}.`, + `SyncService#checkAndUpdateAttempt | Records exceeded max retry count. Portal Id: ${this.user.workspaceId}.`, { tags: { key: 'exceedMaxAttempts', // can be used to search like "key:exceedMaxAttempts"