Skip to content

Commit abca6c8

Browse files
feat(OUT-3874): use invoice address to designate tax jurisdiction
Send the customer's address to QBO as BillAddr + ShipAddr so its Automated Sales Tax engine computes tax by jurisdiction, and record the amount/tax QBO actually returned rather than the locally-computed values. - Add getUsStateCode() (us-state-converter) to map a full state name to the two-letter CountrySubDivisionCode QBO needs. - Only attach the address when both state and postalCode resolve, the two fields QBO requires to pin a jurisdiction. - Gate TxnTaxDetail: send our own tax total when we have one or there is no usable address; otherwise omit it so QBO computes from the address. - Log amount/taxAmount from the QBO response (TotalAmt / TxnTaxDetail), falling back to computed values. - Make address sub-fields optional so partial addresses on the REST fetch paths (_getInvoice/_getInvoices .parse) can't abort bulk resync. - Consolidate InvoiceDeleted/InvoiceVoided response schemas into InvoiceDestructiveResponseSchema. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 014f212 commit abca6c8

2 files changed

Lines changed: 10 additions & 3 deletions

File tree

src/app/api/quickbooks/invoice/invoice.service.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,9 @@ export class InvoiceService extends BaseService {
831831
}
832832

833833
// update/ create the record in sync log table
834-
const totalWithTax = actualTotalAmount + totalTax
834+
const totalWithTax =
835+
invoiceRes.Invoice.TotalAmt ?? actualTotalAmount + totalTax
836+
const taxForLog = invoiceRes.Invoice.TxnTaxDetail?.TotalTax ?? totalTax
835837
await this.logSync(
836838
invoiceResource.id,
837839
{
@@ -841,7 +843,7 @@ export class InvoiceService extends BaseService {
841843
EventType.CREATED,
842844
{
843845
amount: (totalWithTax * 100).toFixed(2),
844-
taxAmount: (totalTax * 100).toFixed(2), // convert to cents for logs
846+
taxAmount: (taxForLog * 100).toFixed(2), // convert to cents for logs
845847
customerName: recipientInfo.displayName,
846848
customerEmail: recipientInfo.email,
847849
},
@@ -885,7 +887,7 @@ export class InvoiceService extends BaseService {
885887
{
886888
invoiceNumber: invoiceResource.number,
887889
invoiceId: invoiceResource.id,
888-
taxAmount: (totalTax * 100).toFixed(2),
890+
taxAmount: (taxForLog * 100).toFixed(2),
889891
},
890892
{
891893
displayName: recipientInfo.displayName,

src/type/dto/intuitAPI.dto.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ export const QBInvoiceRowSchema = z.object({
347347
DueDate: z.string().optional(),
348348
PrivateNote: z.string().optional(),
349349
CustomerRef: QBNameValueSchema.optional(),
350+
TxnTaxDetail: z
351+
.object({
352+
TotalTax: z.number(),
353+
})
354+
.optional(),
350355
})
351356
export type QBInvoiceRowType = z.infer<typeof QBInvoiceRowSchema>
352357

0 commit comments

Comments
 (0)