Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,54 @@ describe('BillingAccountLineItemsModal', () => {
{
amount: '762.66',
date: '2026-06-02T13:10:48.235Z',
externalId: 'assignment-5245',
externalId: 'assignment-5245-finance',
externalName: 'Eng BA',
externalType: 'ENGAGEMENT',
memberPaymentAmount: '753.42',
},
],
consumedBudget: 762.66,
markup: 0.01226408,
totalBudgetRemaining: 237.34,
})

await waitFor(() => {
expect(screen.getByText('$342.00'))
.toBeTruthy()
expect(screen.getByText('$420.66'))
.toBeTruthy()
})
expect(screen.queryByText('$753.42'))
.toBeNull()
expect(screen.queryByText('$9.24'))
.toBeNull()
expect(mockedFetchAssignmentPaymentSplits)
.toHaveBeenCalledWith('assignment-5245-finance')
})

it('uses matching finance engagement payment splits before stale billing-account split fields', async () => {
mockedFetchAssignmentPaymentSplits.mockResolvedValue([
{
amount: 762.66,
billingAccountId: '80001063',
challengeFee: '420.66',
paymentAmount: '342.00',
paymentId: 'd2223b35-10fc-410e-b3f5-6d6ac482caef',
},
])

renderModal({
...baseBillingAccountDetails,
consumedAmounts: [
{
amount: '762.66',
challengeFee: '9.24',
date: '2026-06-02T13:10:48.235Z',
externalId: 'assignment-5245-stale',
externalName: 'Eng BA',
externalType: 'ENGAGEMENT',
memberPaymentAmount: '753.42',
paymentAmount: '753.42',
},
],
consumedBudget: 762.66,
Expand All @@ -454,7 +498,7 @@ describe('BillingAccountLineItemsModal', () => {
expect(screen.queryByText('$9.24'))
.toBeNull()
expect(mockedFetchAssignmentPaymentSplits)
.toHaveBeenCalledWith('assignment-5245')
.toHaveBeenCalledWith('assignment-5245-stale')
})

it('builds engagement links from assignment-backed billing rows for copilot views', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,16 +379,15 @@ function getChallengeLineItemIds(items: BillingAccountLineItem[]): string[] {
* @param items Normalized billing-account line items.
* @returns Unique assignment ids from engagement consumed rows.
* @remarks Locked engagement rows do not correspond to completed finance
* payments, and rows that already carry the persisted split do not need
* additional finance lookups.
* payments. Consumed rows always hydrate from finance so exact payment splits
* can override stale or markup-derived billing-account aliases.
*/
function getEngagementPaymentAssignmentIds(items: BillingAccountLineItem[]): string[] {
return Array.from(new Set(
items
.filter(item => (
item.externalType === 'ENGAGEMENT'
&& item.status === 'consumed'
&& (item.paymentAmount === undefined || item.challengeFee === undefined)
))
.map(item => normalizeRouteId(item.externalId))
.filter((id): id is string => !!id),
Expand Down Expand Up @@ -643,14 +642,14 @@ function getLineItemChallengeFeeAmount(
billingAccountDetails: BillingAccountDetails,
challengeDetailsById: ChallengeDetailsById | undefined,
): number | undefined {
if (item.externalType === 'ENGAGEMENT' && item.challengeFee !== undefined) {
return Number(item.challengeFee.toFixed(2))
}

if (engagementPaymentSplit?.challengeFee !== undefined) {
return engagementPaymentSplit.challengeFee
}

if (item.externalType === 'ENGAGEMENT' && item.challengeFee !== undefined) {
return Number(item.challengeFee.toFixed(2))
}

const consumedChallengeFeeAmount = getConsumedChallengeFeeAmount(item)

if (consumedChallengeFeeAmount !== undefined) {
Expand Down Expand Up @@ -680,14 +679,14 @@ function getEngagementMemberPaymentAmount(
billingAccountDetails: BillingAccountDetails,
engagementPaymentSplit: EngagementPaymentSplit | undefined,
): number | undefined {
if (item.paymentAmount !== undefined) {
return item.paymentAmount
}

if (engagementPaymentSplit?.paymentAmount !== undefined) {
return engagementPaymentSplit.paymentAmount
}

if (item.paymentAmount !== undefined) {
return item.paymentAmount
}

if (item.memberPaymentAmount !== undefined) {
return item.memberPaymentAmount
}
Expand Down
10 changes: 10 additions & 0 deletions src/apps/work/src/lib/utils/payment.utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ describe('payment.utils', () => {
.toBe('80004466')
})

it('prefers explicit paymentAmount over generic amount when both are present', () => {
const payment: AssignmentPayment = {
amount: 762.66,
paymentAmount: '342.00',
}

expect(getPaymentAmount(payment))
.toBe(342)
})

it('falls back to the total-versus-gross delta for older payment payloads', () => {
const payment: AssignmentPayment = {
details: [
Expand Down
8 changes: 4 additions & 4 deletions src/apps/work/src/lib/utils/payment.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ export function formatCurrency(value: unknown): string {
}

export function getPaymentAmount(payment: AssignmentPayment): number | undefined {
if (payment.amount !== undefined) {
return toNumber(payment.amount)
}

if (payment.paymentAmount !== undefined) {
return toNumber(payment.paymentAmount)
}

if (payment.amount !== undefined) {
return toNumber(payment.amount)
}

const firstDetail = getFirstPaymentDetail(payment)

if (firstDetail) {
Expand Down
Loading