Skip to content

Commit 1d5413c

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
feat(quickbooks): add bounded sales transaction reads
1 parent 5f8f819 commit 1d5413c

3 files changed

Lines changed: 412 additions & 7 deletions

File tree

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
2+
import { QUICKBOOKS_MAX_RESPONSE_BYTES } from '@/tools/quickbooks/client'
3+
import type {
4+
QuickBooksReadSalesTransactionsParams,
5+
QuickBooksReadSalesTransactionsResponse,
6+
QuickBooksSalesTransaction,
7+
} from '@/tools/quickbooks/types'
8+
import {
9+
QUICKBOOKS_LIST_OUTPUTS,
10+
QUICKBOOKS_SALES_TRANSACTION_PROPERTIES,
11+
} from '@/tools/quickbooks/types'
12+
import {
13+
buildQuickBooksEntityUrl,
14+
buildQuickBooksQueryUrl,
15+
getQuickBooksSalesEntity,
16+
getQuickBooksToolHeaders,
17+
transformQuickBooksEntityResponse,
18+
transformQuickBooksListResponse,
19+
} from '@/tools/quickbooks/utils'
20+
import type { ToolConfig } from '@/tools/types'
21+
22+
export const quickbooksReadSalesTransactionsTool: ToolConfig<
23+
QuickBooksReadSalesTransactionsParams,
24+
QuickBooksReadSalesTransactionsResponse
25+
> = {
26+
id: 'quickbooks_read_sales_transactions',
27+
name: 'QuickBooks Read Sales Transactions',
28+
description:
29+
'List or read one estimate, invoice, sales receipt, payment, credit memo, or refund receipt',
30+
version: '1.0.0',
31+
params: {
32+
accessToken: {
33+
type: 'string',
34+
required: true,
35+
visibility: 'hidden',
36+
description: 'QuickBooks OAuth access token',
37+
},
38+
realmId: {
39+
type: 'string',
40+
required: true,
41+
visibility: 'hidden',
42+
description: 'QuickBooks company ID derived from the connected credential',
43+
},
44+
transactionType: {
45+
type: 'string',
46+
required: true,
47+
visibility: 'user-or-llm',
48+
description: 'Sales transaction type to read',
49+
},
50+
readMode: {
51+
type: 'string',
52+
required: true,
53+
visibility: 'user-or-llm',
54+
description: 'Whether to list transactions or read one transaction by ID',
55+
},
56+
transactionId: {
57+
type: 'string',
58+
required: false,
59+
visibility: 'user-or-llm',
60+
description: 'QuickBooks transaction ID, required for by-ID reads',
61+
},
62+
startPosition: {
63+
type: 'number',
64+
required: false,
65+
visibility: 'user-or-llm',
66+
default: 1,
67+
description: 'One-based position of the first list record to return',
68+
},
69+
maxResults: {
70+
type: 'number',
71+
required: false,
72+
visibility: 'user-or-llm',
73+
default: 25,
74+
description: 'Number of list records to request (1–100)',
75+
},
76+
},
77+
oauth: {
78+
required: true,
79+
provider: 'quickbooks',
80+
requiredScopes: ['com.intuit.quickbooks.accounting'],
81+
},
82+
errorExtractor: ErrorExtractorId.QUICKBOOKS_FAULT,
83+
request: {
84+
url: (params) => {
85+
const config = getQuickBooksSalesEntity(params.transactionType)
86+
if (params.readMode === 'list') {
87+
return buildQuickBooksQueryUrl(
88+
params.realmId,
89+
config.entity,
90+
params.startPosition ?? 1,
91+
params.maxResults ?? 25
92+
).toString()
93+
}
94+
if (params.readMode === 'by_id') {
95+
if (!params.transactionId?.trim()) {
96+
throw new Error('QuickBooks transaction ID is required for by-ID reads')
97+
}
98+
return buildQuickBooksEntityUrl(
99+
params.realmId,
100+
config.resource,
101+
params.transactionId
102+
).toString()
103+
}
104+
throw new Error(`Unsupported QuickBooks sales read mode: ${String(params.readMode)}`)
105+
},
106+
method: 'GET',
107+
headers: (params) => getQuickBooksToolHeaders(params.accessToken),
108+
retry: { enabled: false },
109+
maxResponseBytes: QUICKBOOKS_MAX_RESPONSE_BYTES,
110+
},
111+
transformResponse: async (response, params) => {
112+
if (!params) throw new Error('QuickBooks sales transaction parameters are required')
113+
const config = getQuickBooksSalesEntity(params.transactionType)
114+
if (params.readMode === 'list') {
115+
const result = await transformQuickBooksListResponse<QuickBooksSalesTransaction>(
116+
response,
117+
{
118+
...params,
119+
startPosition: params.startPosition ?? 1,
120+
maxResults: params.maxResults ?? 25,
121+
},
122+
config.entity
123+
)
124+
return {
125+
success: true,
126+
output: { transactionType: params.transactionType, ...result.output },
127+
}
128+
}
129+
if (params.readMode === 'by_id') {
130+
const result = await transformQuickBooksEntityResponse<QuickBooksSalesTransaction>(
131+
response,
132+
config.entity
133+
)
134+
return {
135+
success: true,
136+
output: { transactionType: params.transactionType, item: result.item, time: result.time },
137+
}
138+
}
139+
throw new Error(`Unsupported QuickBooks sales read mode: ${String(params.readMode)}`)
140+
},
141+
outputs: {
142+
transactionType: { type: 'string', description: 'Sales transaction type returned' },
143+
item: {
144+
type: 'json',
145+
description: 'Single native QuickBooks sales transaction',
146+
optional: true,
147+
properties: QUICKBOOKS_SALES_TRANSACTION_PROPERTIES,
148+
},
149+
items: {
150+
type: 'array',
151+
description: 'Native QuickBooks sales transactions',
152+
optional: true,
153+
items: { type: 'json', properties: QUICKBOOKS_SALES_TRANSACTION_PROPERTIES },
154+
},
155+
...QUICKBOOKS_LIST_OUTPUTS,
156+
},
157+
}

0 commit comments

Comments
 (0)