Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: tie our systems with Anrok taxes #1683

Merged
merged 25 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2d5de0e
feat(one-off): create invoice with taxes from provider
ansmonjol Aug 16, 2024
0f08b83
misc: remove cache on useIntegration query
ansmonjol Aug 23, 2024
b43daf8
feat(invoiceDetails): display alert
keellyp Aug 16, 2024
a6dc68d
feat(invoiceDetails): display failed status
keellyp Aug 19, 2024
dcb8e45
feat(invoiceDetails): display - in tax row
keellyp Aug 19, 2024
f02df7d
feat(lago-210): retry failed invoices
keellyp Aug 19, 2024
6234ce6
feat(lago-211): status updates
keellyp Aug 20, 2024
c5f8454
fix: update available actions for failed invoices in table
keellyp Aug 20, 2024
30b8141
fix: replace translations
keellyp Aug 20, 2024
60d5d35
fix: review
keellyp Aug 20, 2024
48847de
misc(customerInvoiceList): show - if failed status
ansmonjol Aug 23, 2024
713ee3f
misc: fix invoice actions display order
ansmonjol Aug 23, 2024
be33aa6
misc: better error toast on sync invoice fail
ansmonjol Aug 23, 2024
5df2138
feat: display draft badge with warning if errorDetails
ansmonjol Aug 23, 2024
3190518
bug: change default badge icon color
ansmonjol Aug 26, 2024
46ed5d1
misc: silent error tax toast
ansmonjol Aug 26, 2024
d1e22f6
misc: finalize warning badge icon display ruel
ansmonjol Aug 26, 2024
b1a6fda
misc: invoice badge refactor
ansmonjol Aug 27, 2024
513d39a
misc(invoiceDetails): add Anrok retry sync action
ansmonjol Aug 27, 2024
0fd2a0e
misc: arrange finalize invoice error toast message
ansmonjol Aug 27, 2024
d622ae7
misc(taxeError): add warning alert in current usage
ansmonjol Aug 28, 2024
889f8d9
misc: display "global" taxes in invoice footer
ansmonjol Aug 28, 2024
c20f6cc
bug(one-off): fix form sticky footer position
ansmonjol Aug 28, 2024
2cfa2a9
misc: fix linter
ansmonjol Aug 28, 2024
65dd6ad
chore: prevent calling a potentially null attribute
ansmonjol Aug 29, 2024
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
10 changes: 2 additions & 8 deletions src/components/creditNote/CreditNoteFormCalculation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,8 @@ gql`
id
appliedTaxes {
id
tax {
id
name
rate
}
taxName
taxRate
}
}
}
Expand All @@ -58,9 +55,6 @@ gql`
taxName
taxRate
amountCents
tax {
id
}
}
couponsAdjustmentAmountCents
currency
Expand Down
62 changes: 14 additions & 48 deletions src/components/creditNote/__tests__/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@ export const feesMock = {
appliedTaxes: [
{
id: 'tax1',
tax: {
id: 'tax1tax1',
name: 'Tax 1',
rate: 10,
},
taxName: 'Tax 1',
taxRate: 10,
},
],
},
Expand All @@ -39,11 +36,8 @@ export const feesMock = {
appliedTaxes: [
{
id: 'tax2',
tax: {
id: 'tax2tax2',
name: 'Tax 2',
rate: 20,
},
taxName: 'Tax 2',
taxRate: 20,
},
],
},
Expand Down Expand Up @@ -85,19 +79,13 @@ export const feesMock = {
appliedTaxes: [
{
id: 'tax1',
tax: {
id: 'tax1tax1',
name: 'Tax 1',
rate: 10,
},
taxName: 'Tax 1',
taxRate: 10,
},
{
id: 'tax2',
tax: {
id: 'tax2tax2',
name: 'Tax 2',
rate: 20,
},
taxName: 'Tax 2',
taxRate: 20,
},
],
},
Expand Down Expand Up @@ -126,19 +114,13 @@ export const addOnFeeMock = [
appliedTaxes: [
{
id: 'tax1',
tax: {
id: 'tax1tax1',
name: 'Tax 1',
rate: 10,
},
taxName: 'Tax 1',
taxRate: 10,
},
{
id: 'tax2',
tax: {
id: 'tax2tax2',
name: 'Tax 2',
rate: 20,
},
taxName: 'Tax 2',
taxRate: 20,
},
],
},
Expand All @@ -153,25 +135,9 @@ export const addOnFeeMock = [
appliedTaxes: [
{
id: 'tax1',
tax: {
id: 'tax1tax1',
name: 'Tax 1',
rate: 10,
},
taxName: 'Tax 1',
taxRate: 10,
},
],
},
]

// export const invoiceMock = {
// id: '1234',
// couponsAmountCents: '1010',
// paymentStatus: InvoicePaymentStatusTypeEnum.Pending,
// creditableAmountCents: '0',
// refundableAmountCents: '0',
// feesAmountCents: '62833',
// currency: CurrencyEnum.Eur,
// versionNumber: 3,
// fees: addOnFeeMock,
// invoiceSubscriptions: feesMock,
// }
7 changes: 2 additions & 5 deletions src/components/creditNote/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ export type FromFee = {
succeededAt?: string
appliedTaxes?: {
id: string
tax: {
id: string
name: string
rate: number
}
taxName: string
taxRate: number
}[]
}

Expand Down
143 changes: 67 additions & 76 deletions src/components/customers/CustomerInvoicesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@ import { FC, useRef } from 'react'
import { generatePath, useNavigate } from 'react-router-dom'
import styled from 'styled-components'

import {
InfiniteScroll,
Status,
StatusProps,
StatusType,
Table,
Tooltip,
Typography,
} from '~/components/designSystem'
import { InfiniteScroll, Status, Table, Tooltip, Typography } from '~/components/designSystem'
import { addToast, hasDefinedGQLError } from '~/core/apolloClient'
import { invoiceStatusMapping, paymentStatusMapping } from '~/core/constants/statusInvoiceMapping'
import { intlFormatNumber } from '~/core/formats/intlFormatNumber'
import { CUSTOMER_INVOICE_DETAILS_ROUTE } from '~/core/router'
import { deserializeAmount } from '~/core/serializers/serializeAmount'
Expand Down Expand Up @@ -54,11 +47,17 @@ gql`
currency
voidable
paymentDisputeLostAt
taxProviderVoidable
customer {
id
name
applicableTimezone
}
errorDetails {
errorCode
errorDetails
}

...InvoiceForFinalizeInvoice
...InvoiceForUpdateInvoicePaymentStatus
}
Expand Down Expand Up @@ -97,54 +96,6 @@ gql`
${InvoiceForUpdateInvoicePaymentStatusFragmentDoc}
`

const mapStatusConfig = ({
status,
paymentStatus,
paymentOverdue,
paymentDisputeLostAt,
}: {
status: InvoiceStatusTypeEnum
paymentStatus: InvoicePaymentStatusTypeEnum
paymentOverdue: boolean
paymentDisputeLostAt?: string
}): StatusProps => {
if (paymentDisputeLostAt) {
return { label: 'disputed', type: StatusType.danger }
}

if (status === InvoiceStatusTypeEnum.Draft) {
return { label: 'draft', type: StatusType.outline }
}

if (status === InvoiceStatusTypeEnum.Voided) {
return { label: 'voided', type: StatusType.disabled }
}

if (paymentStatus === InvoicePaymentStatusTypeEnum.Succeeded) {
return { label: 'succeeded', type: StatusType.success }
}

if (paymentOverdue) {
return { label: 'overdue', type: StatusType.danger }
}

if (
status === InvoiceStatusTypeEnum.Finalized &&
paymentStatus === InvoicePaymentStatusTypeEnum.Failed
) {
return { label: 'failed', type: StatusType.warning }
}

if (
status === InvoiceStatusTypeEnum.Finalized &&
paymentStatus === InvoicePaymentStatusTypeEnum.Pending
) {
return { label: 'pending', type: StatusType.default }
}

return { label: 'n/a', type: StatusType.default }
}

interface CustomerInvoicesListProps {
isLoading: boolean
hasError?: boolean
Expand Down Expand Up @@ -252,21 +203,23 @@ export const CustomerInvoicesList: FC<CustomerInvoicesListProps> = ({
{
key: 'status',
minWidth: 80,
title: translate(
context === 'draft'
? 'text_63ac86d797f728a87b2f9fa7'
: 'text_63b5d225b075850e0fe489f4',
),
content: ({ status, paymentStatus, paymentOverdue, paymentDisputeLostAt }) => {
title: translate('text_63ac86d797f728a87b2f9fa7'),
content: ({ status, errorDetails, taxProviderVoidable }) => {
const showWarningIcon =
(!!errorDetails?.length && status !== InvoiceStatusTypeEnum.Failed) ||
taxProviderVoidable

return (
<Status
{...mapStatusConfig({
status,
paymentStatus,
paymentOverdue,
paymentDisputeLostAt,
})}
/>
<Tooltip
placement="top-start"
disableHoverListener={!showWarningIcon}
title={translate('text_1724674592260h33v56rycaw')}
>
<Status
{...invoiceStatusMapping({ status })}
endIcon={showWarningIcon ? 'warning-unfilled' : undefined}
/>
</Tooltip>
)
},
},
Expand All @@ -283,6 +236,8 @@ export const CustomerInvoicesList: FC<CustomerInvoicesListProps> = ({
minWidth: 160,
title: translate('text_63ac86d797f728a87b2f9fb9'),
content: (invoice) => {
if (invoice.status === InvoiceStatusTypeEnum.Failed) return '-'

const currency = invoice.currency || CurrencyEnum.Usd
const amount = deserializeAmount(invoice.totalAmountCents, currency)

Expand All @@ -293,6 +248,38 @@ export const CustomerInvoicesList: FC<CustomerInvoicesListProps> = ({
)
},
},
context === 'finalized'
? {
key: 'paymentStatus',
minWidth: 120,
title: translate('text_63b5d225b075850e0fe489f4'),
content: ({ status, paymentStatus, paymentOverdue, paymentDisputeLostAt }) => {
if (status !== InvoiceStatusTypeEnum.Finalized) {
return null
}

return (
<Tooltip
placement="top"
title={
!!paymentDisputeLostAt
? translate('text_172416478461328edo4vwz05')
: undefined
}
>
<Status
{...paymentStatusMapping({
status,
paymentStatus,
paymentOverdue,
})}
endIcon={!!paymentDisputeLostAt ? 'warning-unfilled' : undefined}
/>
</Tooltip>
)
},
}
: null,
{
key: 'issuingDate',
minWidth: 104,
Expand All @@ -316,18 +303,22 @@ export const CustomerInvoicesList: FC<CustomerInvoicesListProps> = ({
const { status, paymentStatus, voidable } = invoice

const canDownload =
status !== InvoiceStatusTypeEnum.Draft && hasPermissions(['invoicesView'])
const canFinalize = hasPermissions(['invoicesUpdate'])
![InvoiceStatusTypeEnum.Draft, InvoiceStatusTypeEnum.Failed].includes(status) &&
hasPermissions(['invoicesView'])
const canFinalize =
![InvoiceStatusTypeEnum.Failed].includes(status) && hasPermissions(['invoicesUpdate'])
const canRetryCollect =
status === InvoiceStatusTypeEnum.Finalized &&
[InvoicePaymentStatusTypeEnum.Failed, InvoicePaymentStatusTypeEnum.Pending].includes(
paymentStatus,
) &&
hasPermissions(['invoicesSend'])
const canUpdatePaymentStatus =
status !== InvoiceStatusTypeEnum.Draft &&
status !== InvoiceStatusTypeEnum.Voided &&
hasPermissions(['invoicesUpdate'])
![
InvoiceStatusTypeEnum.Draft,
InvoiceStatusTypeEnum.Voided,
InvoiceStatusTypeEnum.Failed,
].includes(status) && hasPermissions(['invoicesUpdate'])
const canVoid =
status === InvoiceStatusTypeEnum.Finalized &&
[InvoicePaymentStatusTypeEnum.Pending, InvoicePaymentStatusTypeEnum.Failed].includes(
Expand Down
7 changes: 6 additions & 1 deletion src/components/customers/CustomerInvoicesTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ export const CustomerInvoicesTab = ({ customerId, customerTimezone }: CustomerIn
variables: {
customerId,
limit: 20,
status: [InvoiceStatusTypeEnum.Finalized, InvoiceStatusTypeEnum.Voided],
status: [
InvoiceStatusTypeEnum.Finalized,
InvoiceStatusTypeEnum.Voided,
InvoiceStatusTypeEnum.Failed,
],
},
notifyOnNetworkStatusChange: true,
})
Expand All @@ -94,6 +98,7 @@ export const CustomerInvoicesTab = ({ customerId, customerTimezone }: CustomerIn
isLoading
customerTimezone={customerTimezone}
customerId={customerId}
context="finalized"
/>
</LoadingState>
) : !invoicesDraft?.length &&
Expand Down
Loading
Loading