diff --git a/.github/workflows/cypress.old b/.github/workflows/cypress.old new file mode 100644 index 000000000..605839498 --- /dev/null +++ b/.github/workflows/cypress.old @@ -0,0 +1,57 @@ +# name: TestE2E + +# on: +# pull_request: +# types: [opened, reopened, review_requested, ready_for_review, synchronize] + +# jobs: +# cypress-run: +# if: github.event.pull_request.draft == false +# name: Run Test E2E +# runs-on: ubuntu-latest +# steps: +# - name: Check out Git repository +# uses: actions/checkout@v4 + +# - name: Checkout API Git repository +# uses: actions/checkout@v4 +# with: +# repository: getlago/lago-api +# ref: ${{ github.event.inputs.api_branch }} +# path: api +# token: ${{ secrets.GH_TOKEN }} + +# - name: Build Front local image +# run: | +# docker build -t getlago/front:ci ./ + +# - name: Build API local image +# run: | +# docker build -t getlago/api:ci ./api + +# - name: Launch APP + API +# env: +# LAGO_RSA_PRIVATE_KEY: ${{ secrets.LAGO_RSA_PRIVATE_KEY }} +# LAGO_LICENSE: ${{ secrets.LAGO_LICENSE }} +# run: | +# docker-compose -f ./ci/docker-compose.ci.yml up -d db redis api front + +# - name: Set up Node.js +# uses: actions/setup-node@v4 +# with: +# node-version: 20 + +# - name: Cypress run +# uses: cypress-io/github-action@v6 +# env: +# CYPRESS_GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} +# with: +# browser: chrome +# record: false +# config: baseUrl=http://localhost,viewportHeight=99999,viewportWidth=1280 +# spec: | +# cypress/e2e/00-auth/* +# cypress/e2e/10-resources/* +# cypress/e2e/t10-* +# cypress/e2e/t20-* +# cypress/e2e/t30-* \ No newline at end of file diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml deleted file mode 100644 index ca1476f1a..000000000 --- a/.github/workflows/cypress.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: TestE2E - -on: - pull_request: - types: [opened, reopened, review_requested, ready_for_review, synchronize] - -jobs: - cypress-run: - if: github.event.pull_request.draft == false - name: Run Test E2E - runs-on: ubuntu-latest - steps: - - name: Check out Git repository - uses: actions/checkout@v4 - - - name: Checkout API Git repository - uses: actions/checkout@v4 - with: - repository: getlago/lago-api - ref: ${{ github.event.inputs.api_branch }} - path: api - token: ${{ secrets.GH_TOKEN }} - - - name: Build Front local image - run: | - docker build -t getlago/front:ci ./ - - - name: Build API local image - run: | - docker build -t getlago/api:ci ./api - - - name: Launch APP + API - env: - LAGO_RSA_PRIVATE_KEY: ${{ secrets.LAGO_RSA_PRIVATE_KEY }} - LAGO_LICENSE: ${{ secrets.LAGO_LICENSE }} - run: | - docker-compose -f ./ci/docker-compose.ci.yml up -d db redis api front - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Cypress run - uses: cypress-io/github-action@v6 - env: - CYPRESS_GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - with: - browser: chrome - record: false - config: baseUrl=http://localhost,viewportHeight=99999,viewportWidth=1280 - spec: | - cypress/e2e/00-auth/* - cypress/e2e/10-resources/* - cypress/e2e/t10-* - cypress/e2e/t20-* - cypress/e2e/t30-* \ No newline at end of file diff --git a/cypress/e2e/10-resources/t40-create-plan.cy.ts b/cypress/e2e/10-resources/t40-create-plan.cy.ts index dd124ab11..25f5008c8 100644 --- a/cypress/e2e/10-resources/t40-create-plan.cy.ts +++ b/cypress/e2e/10-resources/t40-create-plan.cy.ts @@ -10,181 +10,182 @@ describe('Create plan', () => { cy.get('[data-test="empty"]').should('exist') }) - it('should be able to create a simple plan', () => { - const randomId = Math.round(Math.random() * 1000) - const planName = `plan ${randomId}` - - cy.get('[data-test="create-plan"]').click({ force: true }) - cy.url().should('be.equal', Cypress.config().baseUrl + '/create/plans') - cy.get('input[name="name"]').type(planName) - cy.get('input[name="code"]').type(planName) - cy.get('[data-test="show-description"]').click({ force: true }) - cy.get('textarea[name="description"]').type('I am a description') - cy.get('input[name="amountCents"]').type('30000') - cy.get('[data-test="submit"]').click({ force: true }) - cy.url().should('include', '/overview') - cy.contains(planName).should('exist') - }) - - it('should be able to create a plan with all 0 dimension charges and submit', () => { - cy.get('[data-test="create-plan"]').click({ force: true }) - cy.url().should('be.equal', Cypress.config().baseUrl + '/create/plans') - cy.get('input[name="name"]').type(planWithChargesName) - cy.get('[data-test="submit"]').should('be.disabled') - cy.get('input[name="code"]').type(planWithChargesName) - cy.get('[data-test="submit"]').should('be.disabled') - cy.get('[data-test="show-description"]').click({ force: true }) - cy.get('textarea[name="description"]').type('I am a description') - cy.get('[data-test="submit"]').should('be.disabled') - cy.get('input[name="amountCents"]').type('30000') - cy.get('[data-test="submit"]').should('not.be.disabled') - cy.get('input[name="amountCurrency"]').click({ force: true }) - cy.get('[data-test="USD"]').click({ force: true }) - - // Standard - cy.get('[data-test="add-charge"]').first().click({ force: true }) - cy.get('[data-test="add-metered-charge"]').first().click({ force: true }) - cy.get('[data-option-index="0"]').click({ force: true }) - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('input[name="chargeModel"]').last().should('have.value', 'Standard pricing') - cy.get('input[name="properties.amount"]').type('5000') - cy.get('[data-test="submit"]').should('not.be.disabled') - - // Graduated - cy.get('[data-test="add-charge"]').last().click({ force: true }) - cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) - cy.get('[data-option-index="1"]').click({ force: true }) - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('input[name="chargeModel"]').last().click({ force: true }) - cy.get('[data-test="graduated"]').click({ force: true }) - cy.get('input[name="chargeModel"]').last().should('have.value', 'Graduated pricing') - cy.get('[data-test="row-2"]').should('not.exist') - cy.get('[data-test="add-tier"]').click({ force: true }) - cy.get('[data-test="row-2"]').should('exist') - cy.get('[data-test="cell-amount-0"]').type('1') - cy.get('[data-test="cell-amount-1"]').type('1') - cy.get('[data-test="cell-amount-2"]').type('1') - cy.get('[data-test="submit"]').should('not.be.disabled') - - // Graduated percentage - cy.get('[data-test="add-charge"]').last().click({ force: true }) - cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) - cy.get('[data-option-index="1"]').click({ force: true }) - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('input[name="chargeModel"]').last().click({ force: true }) - cy.get('[data-test="graduated_percentage"]').click({ force: true }) - cy.get('[data-test="charge-accordion-2"]').within(() => { - cy.get('input[name="chargeModel"]') - .last() - .should('have.value', 'Graduated percentage pricing') - cy.get('[data-test="add-tier"]').last().click({ force: true }) - cy.get('[data-test="cell-rate-0"]').type('1') - cy.get('[data-test="cell-rate-1"]').type('1') - cy.get('[data-test="cell-rate-2"]').type('1') - }) - cy.get('[data-test="row-2"]').should('have.length', 2) - cy.get('[data-test="submit"]').should('not.be.disabled') - - // Package - cy.get('[data-test="add-charge"]').last().click({ force: true }) - cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) - cy.get('[data-option-index="1"]').click({ force: true }) - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('input[name="chargeModel"]').last().click({ force: true }) - cy.get('[data-test="package"]').click({ force: true }) - cy.get('input[name="chargeModel"]').last().should('have.value', 'Package pricing') - cy.get('input[name="properties.amount"]').last().type('1') - cy.get('[data-test="submit"]').should('not.be.disabled') - - // Percentage - cy.get('[data-test="add-charge"]').last().click({ force: true }) - cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) - cy.get('[data-option-index="1"]').click({ force: true }) - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('input[name="chargeModel"]').last().click({ force: true }) - cy.get('[data-test="percentage"]').click({ force: true }) - cy.get('input[name="chargeModel"]').last().should('have.value', 'Percentage pricing') - cy.get('input[name="properties.rate"]').last().type('1') - cy.get('[data-test="add-fixed-fee"]').click({ force: true }) - cy.get('input[name="properties.fixedAmount"]').should('exist') - cy.get('[data-test="add-free-units"]').click({ force: true }) - cy.get('[data-test="add-free-units-events"]').click({ force: true }) - cy.get('[data-test="free-unit-per-event"] input').should('exist') - cy.get('[data-test="add-free-units"]').click({ force: true }) - cy.get('[data-test="add-free-units-total-amount"]').click({ force: true }) - cy.get('[data-test="free-unit-per-total-aggregation"] input').should('exist') - - // Min max - cy.get('[data-test="add-min-max-drowdown-cta"]').click({ force: true }) - cy.get('[data-test="add-min-cta"]').click({ force: true }) - cy.get('[data-test="per-transaction-min-amount"]').should('exist') - cy.get('[data-test="add-min-max-drowdown-cta"]').click({ force: true }) - cy.get('[data-test="add-max-cta"]').click({ force: true }) - cy.get('[data-test="per-transaction-max-amount"]').should('exist') - cy.get('[data-test="submit"]').should('not.be.disabled') - - // Volume - cy.get('[data-test="add-charge"]').last().click({ force: true }) - cy.get('[data-test="add-recurring-charge"]').last().click({ force: true }) - cy.get('[data-option-index="0"]').click({ force: true }) - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('input[name="chargeModel"]').last().click({ force: true }) - cy.get('[data-test="volume"]').click({ force: true }) - cy.get('input[name="chargeModel"]').last().should('have.value', 'Volume pricing') - cy.get('[data-test="add-tier"]').last().click({ force: true }) - cy.get('[data-test="cell-amount-0"]').last().type('1') - cy.get('[data-test="cell-amount-1"]').last().type('1') - cy.get('[data-test="cell-amount-2"]').last().type('1') - cy.get('[data-test="submit"]').should('not.be.disabled') - - cy.get('[data-test="submit"]').click({ force: true }) - cy.url().should('include', '/overview') - cy.contains(planWithChargesName).should('exist') - }) - - describe('anti-regression', () => { - // https://github.com/getlago/lago-front/pull/792 - it('should be able to edit percentage charge without data loss', () => { - const randomId = Math.round(Math.random() * 1000) - const planName = `plan ${randomId}` - - // Default plan data - cy.get('[data-test="create-plan"]').click({ force: true }) - cy.url().should('be.equal', Cypress.config().baseUrl + '/create/plans') - cy.get('input[name="name"]').type(planName) - cy.get('input[name="code"]').type(planName) - cy.get('[data-test="show-description"]').click({ force: true }) - cy.get('textarea[name="description"]').type('I am a description') - cy.get('input[name="amountCents"]').type('30000') - - // Config charge - cy.get('[data-test="add-charge"]').last().click({ force: true }) - cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) - cy.get('[data-option-index="1"]').click({ force: true }) - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('input[name="chargeModel"]').last().click({ force: true }) - cy.get('[data-test="percentage"]').click({ force: true }) - cy.get('input[name="chargeModel"]').last().should('have.value', 'Percentage pricing') - cy.get('input[name="properties.rate"]').last().type('1') - cy.get('[data-test="add-fixed-fee"]').click({ force: true }) - cy.get('input[name="properties.fixedAmount"]').last().type('1') - cy.get('[data-test="add-free-units"]').click({ force: true }) - cy.get('[data-test="add-free-units-events"]').click({ force: true }) - cy.get('[data-test="free-unit-per-event"] input').last().type('1') - cy.get('[data-test="add-free-units"]').click({ force: true }) - cy.get('[data-test="add-free-units-total-amount"]').click({ force: true }) - cy.get('[data-test="free-unit-per-total-aggregation"] input').last().type('1') - - // Test regression scenario - cy.get('[data-test="remove-fixed-fee"]').click({ force: true }) - cy.get('[data-test="remove-free-units-per-event"]').click({ force: true }) - cy.get('[data-test="remove-free-unit-per-total-aggregation"]').click({ force: true }) - cy.get('[data-test="submit"]').should('not.be.disabled') - cy.get('input[name="properties.rate"]').should('have.value', '1') - - cy.get('[data-test="submit"]').click({ force: true }) - cy.url().should('include', '/overview') - cy.contains(planName).should('exist') - }) - }) + // TODO: uncomment when CI e2e api setup is fixed + // it('should be able to create a simple plan', () => { + // const randomId = Math.round(Math.random() * 1000) + // const planName = `plan ${randomId}` + + // cy.get('[data-test="create-plan"]').click({ force: true }) + // cy.url().should('be.equal', Cypress.config().baseUrl + '/create/plans') + // cy.get('input[name="name"]').type(planName) + // cy.get('input[name="code"]').type(planName) + // cy.get('[data-test="show-description"]').click({ force: true }) + // cy.get('textarea[name="description"]').type('I am a description') + // cy.get('input[name="amountCents"]').type('30000') + // cy.get('[data-test="submit"]').click({ force: true }) + // cy.url().should('include', '/overview') + // cy.contains(planName).should('exist') + // }) + + // it('should be able to create a plan with all 0 dimension charges and submit', () => { + // cy.get('[data-test="create-plan"]').click({ force: true }) + // cy.url().should('be.equal', Cypress.config().baseUrl + '/create/plans') + // cy.get('input[name="name"]').type(planWithChargesName) + // cy.get('[data-test="submit"]').should('be.disabled') + // cy.get('input[name="code"]').type(planWithChargesName) + // cy.get('[data-test="submit"]').should('be.disabled') + // cy.get('[data-test="show-description"]').click({ force: true }) + // cy.get('textarea[name="description"]').type('I am a description') + // cy.get('[data-test="submit"]').should('be.disabled') + // cy.get('input[name="amountCents"]').type('30000') + // cy.get('[data-test="submit"]').should('not.be.disabled') + // cy.get('input[name="amountCurrency"]').click({ force: true }) + // cy.get('[data-test="USD"]').click({ force: true }) + + // // Standard + // cy.get('[data-test="add-charge"]').first().click({ force: true }) + // cy.get('[data-test="add-metered-charge"]').first().click({ force: true }) + // cy.get('[data-option-index="0"]').click({ force: true }) + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('input[name="chargeModel"]').last().should('have.value', 'Standard pricing') + // cy.get('input[name="properties.amount"]').type('5000') + // cy.get('[data-test="submit"]').should('not.be.disabled') + + // // Graduated + // cy.get('[data-test="add-charge"]').last().click({ force: true }) + // cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) + // cy.get('[data-option-index="1"]').click({ force: true }) + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('input[name="chargeModel"]').last().click({ force: true }) + // cy.get('[data-test="graduated"]').click({ force: true }) + // cy.get('input[name="chargeModel"]').last().should('have.value', 'Graduated pricing') + // cy.get('[data-test="row-2"]').should('not.exist') + // cy.get('[data-test="add-tier"]').click({ force: true }) + // cy.get('[data-test="row-2"]').should('exist') + // cy.get('[data-test="cell-amount-0"]').type('1') + // cy.get('[data-test="cell-amount-1"]').type('1') + // cy.get('[data-test="cell-amount-2"]').type('1') + // cy.get('[data-test="submit"]').should('not.be.disabled') + + // // Graduated percentage + // cy.get('[data-test="add-charge"]').last().click({ force: true }) + // cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) + // cy.get('[data-option-index="1"]').click({ force: true }) + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('input[name="chargeModel"]').last().click({ force: true }) + // cy.get('[data-test="graduated_percentage"]').click({ force: true }) + // cy.get('[data-test="charge-accordion-2"]').within(() => { + // cy.get('input[name="chargeModel"]') + // .last() + // .should('have.value', 'Graduated percentage pricing') + // cy.get('[data-test="add-tier"]').last().click({ force: true }) + // cy.get('[data-test="cell-rate-0"]').type('1') + // cy.get('[data-test="cell-rate-1"]').type('1') + // cy.get('[data-test="cell-rate-2"]').type('1') + // }) + // cy.get('[data-test="row-2"]').should('have.length', 2) + // cy.get('[data-test="submit"]').should('not.be.disabled') + + // // Package + // cy.get('[data-test="add-charge"]').last().click({ force: true }) + // cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) + // cy.get('[data-option-index="1"]').click({ force: true }) + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('input[name="chargeModel"]').last().click({ force: true }) + // cy.get('[data-test="package"]').click({ force: true }) + // cy.get('input[name="chargeModel"]').last().should('have.value', 'Package pricing') + // cy.get('input[name="properties.amount"]').last().type('1') + // cy.get('[data-test="submit"]').should('not.be.disabled') + + // // Percentage + // cy.get('[data-test="add-charge"]').last().click({ force: true }) + // cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) + // cy.get('[data-option-index="1"]').click({ force: true }) + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('input[name="chargeModel"]').last().click({ force: true }) + // cy.get('[data-test="percentage"]').click({ force: true }) + // cy.get('input[name="chargeModel"]').last().should('have.value', 'Percentage pricing') + // cy.get('input[name="properties.rate"]').last().type('1') + // cy.get('[data-test="add-fixed-fee"]').click({ force: true }) + // cy.get('input[name="properties.fixedAmount"]').should('exist') + // cy.get('[data-test="add-free-units"]').click({ force: true }) + // cy.get('[data-test="add-free-units-events"]').click({ force: true }) + // cy.get('[data-test="free-unit-per-event"] input').should('exist') + // cy.get('[data-test="add-free-units"]').click({ force: true }) + // cy.get('[data-test="add-free-units-total-amount"]').click({ force: true }) + // cy.get('[data-test="free-unit-per-total-aggregation"] input').should('exist') + + // // Min max + // cy.get('[data-test="add-min-max-drowdown-cta"]').click({ force: true }) + // cy.get('[data-test="add-min-cta"]').click({ force: true }) + // cy.get('[data-test="per-transaction-min-amount"]').should('exist') + // cy.get('[data-test="add-min-max-drowdown-cta"]').click({ force: true }) + // cy.get('[data-test="add-max-cta"]').click({ force: true }) + // cy.get('[data-test="per-transaction-max-amount"]').should('exist') + // cy.get('[data-test="submit"]').should('not.be.disabled') + + // // Volume + // cy.get('[data-test="add-charge"]').last().click({ force: true }) + // cy.get('[data-test="add-recurring-charge"]').last().click({ force: true }) + // cy.get('[data-option-index="0"]').click({ force: true }) + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('input[name="chargeModel"]').last().click({ force: true }) + // cy.get('[data-test="volume"]').click({ force: true }) + // cy.get('input[name="chargeModel"]').last().should('have.value', 'Volume pricing') + // cy.get('[data-test="add-tier"]').last().click({ force: true }) + // cy.get('[data-test="cell-amount-0"]').last().type('1') + // cy.get('[data-test="cell-amount-1"]').last().type('1') + // cy.get('[data-test="cell-amount-2"]').last().type('1') + // cy.get('[data-test="submit"]').should('not.be.disabled') + + // cy.get('[data-test="submit"]').click({ force: true }) + // cy.url().should('include', '/overview') + // cy.contains(planWithChargesName).should('exist') + // }) + + // describe('anti-regression', () => { + // // https://github.com/getlago/lago-front/pull/792 + // it('should be able to edit percentage charge without data loss', () => { + // const randomId = Math.round(Math.random() * 1000) + // const planName = `plan ${randomId}` + + // // Default plan data + // cy.get('[data-test="create-plan"]').click({ force: true }) + // cy.url().should('be.equal', Cypress.config().baseUrl + '/create/plans') + // cy.get('input[name="name"]').type(planName) + // cy.get('input[name="code"]').type(planName) + // cy.get('[data-test="show-description"]').click({ force: true }) + // cy.get('textarea[name="description"]').type('I am a description') + // cy.get('input[name="amountCents"]').type('30000') + + // // Config charge + // cy.get('[data-test="add-charge"]').last().click({ force: true }) + // cy.get('[data-test="add-metered-charge"]').last().click({ force: true }) + // cy.get('[data-option-index="1"]').click({ force: true }) + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('input[name="chargeModel"]').last().click({ force: true }) + // cy.get('[data-test="percentage"]').click({ force: true }) + // cy.get('input[name="chargeModel"]').last().should('have.value', 'Percentage pricing') + // cy.get('input[name="properties.rate"]').last().type('1') + // cy.get('[data-test="add-fixed-fee"]').click({ force: true }) + // cy.get('input[name="properties.fixedAmount"]').last().type('1') + // cy.get('[data-test="add-free-units"]').click({ force: true }) + // cy.get('[data-test="add-free-units-events"]').click({ force: true }) + // cy.get('[data-test="free-unit-per-event"] input').last().type('1') + // cy.get('[data-test="add-free-units"]').click({ force: true }) + // cy.get('[data-test="add-free-units-total-amount"]').click({ force: true }) + // cy.get('[data-test="free-unit-per-total-aggregation"] input').last().type('1') + + // // Test regression scenario + // cy.get('[data-test="remove-fixed-fee"]').click({ force: true }) + // cy.get('[data-test="remove-free-units-per-event"]').click({ force: true }) + // cy.get('[data-test="remove-free-unit-per-total-aggregation"]').click({ force: true }) + // cy.get('[data-test="submit"]').should('not.be.disabled') + // cy.get('input[name="properties.rate"]').should('have.value', '1') + + // cy.get('[data-test="submit"]').click({ force: true }) + // cy.url().should('include', '/overview') + // cy.contains(planName).should('exist') + // }) + // }) }) diff --git a/cypress/e2e/10-resources/t50-edit-plan.cy.ts b/cypress/e2e/10-resources/t50-edit-plan.cy.ts index 96cd83cac..866ad2cc7 100644 --- a/cypress/e2e/10-resources/t50-edit-plan.cy.ts +++ b/cypress/e2e/10-resources/t50-edit-plan.cy.ts @@ -1,45 +1,48 @@ import { customerName, planWithChargesName } from '../../support/reusableConstants' describe('Edit plan', () => { - it('should be able to close the form without warning dialog when no data has changed', () => { - cy.visit('/plans') - cy.get(`[data-test="${planWithChargesName}-wrapper"]`).within(() => { - cy.get('[data-test="plan-item-options"]').click({ force: true }) - }) - cy.get('[data-test="tab-internal-button-link-update-plan"]').click({ force: true }) - cy.get('input[name="name"]').should('exist') - cy.get('[data-test="close-create-plan-button"]').click({ force: true }) - cy.get('[data-test="close-create-plan-button"]').should('not.exist') - cy.url().should('include', '/overview') + it('make sure file still exists', () => { + expect(true).to.equal(true) }) + // TODO: uncomment when CI e2e api setup is fixed + // it('should be able to close the form without warning dialog when no data has changed', () => { + // cy.visit('/plans') + // cy.get(`[data-test="${planWithChargesName}-wrapper"]`).within(() => { + // cy.get('[data-test="plan-item-options"]').click({ force: true }) + // }) + // cy.get('[data-test="tab-internal-button-link-update-plan"]').click({ force: true }) + // cy.get('input[name="name"]').should('exist') + // cy.get('[data-test="close-create-plan-button"]').click({ force: true }) + // cy.get('[data-test="close-create-plan-button"]').should('not.exist') + // cy.url().should('include', '/overview') + // }) - it('should be able to update all information of unused plan', () => { - cy.visit('/plans') - cy.get(`[data-test="${planWithChargesName}-wrapper"]`).within(() => { - cy.get('[data-test="plan-item-options"]').click({ force: true }) - }) - cy.get('[data-test="tab-internal-button-link-update-plan"]').click({ force: true }) - cy.get('input[name="name"]').should('not.be.disabled') - cy.get('input[name="code"]').should('not.be.disabled') - cy.get('textarea[name="description"]', { timeout: 10000 }).should('not.be.disabled') - cy.get(`[data-test="fixed-fee-section-accordion"]`).within(() => { - cy.get(`.MuiAccordionSummary-root`).click({ force: true }) - }) - // cy.get('input[name="amountCents"]', { timeout: 10000 }).should('not.be.disabled') - cy.get('input[name="amountCurrency"]').eq(0).should('not.be.disabled') - cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') - cy.get('[data-test="open-charge"]').eq(1).click({ force: true }) - cy.get('input[name="chargeModel"]').should('not.be.disabled') - cy.get('input[name="properties.amount"]').should('not.be.disabled') - // TODO: fix, cause with amountInput introduction - // BE is expecting string where we manage amount as int - // cy.get('[data-test="submit"]').should('be.disabled') + // it('should be able to update all information of unused plan', () => { + // cy.visit('/plans') + // cy.get(`[data-test="${planWithChargesName}-wrapper"]`).within(() => { + // cy.get('[data-test="plan-item-options"]').click({ force: true }) + // }) + // cy.get('[data-test="tab-internal-button-link-update-plan"]').click({ force: true }) + // cy.get('input[name="name"]').should('not.be.disabled') + // cy.get('input[name="code"]').should('not.be.disabled') + // cy.get('textarea[name="description"]', { timeout: 10000 }).should('not.be.disabled') + // cy.get(`[data-test="fixed-fee-section-accordion"]`).within(() => { + // cy.get(`.MuiAccordionSummary-root`).click({ force: true }) + // }) + // // cy.get('input[name="amountCents"]', { timeout: 10000 }).should('not.be.disabled') + // cy.get('input[name="amountCurrency"]').eq(0).should('not.be.disabled') + // cy.get('[data-test="remove-charge"]').should('exist').and('not.be.disabled') + // cy.get('[data-test="open-charge"]').eq(1).click({ force: true }) + // cy.get('input[name="chargeModel"]').should('not.be.disabled') + // cy.get('input[name="properties.amount"]').should('not.be.disabled') + // // TODO: fix, cause with amountInput introduction + // // BE is expecting string where we manage amount as int + // // cy.get('[data-test="submit"]').should('be.disabled') - cy.get('input[name="code"]').type('new code plan with charge') - cy.get('[data-test="submit"]').click({ force: true }) - }) + // cy.get('input[name="code"]').type('new code plan with charge') + // cy.get('[data-test="submit"]').click({ force: true }) + // }) - // TODO: uncomment when CI e2e api setup is fixed // it('should add plan to customer', () => { // cy.visit('/customers') // cy.get(`[data-test="${customerName}"]`).click({ force: true }) diff --git a/cypress/e2e/10-resources/t60-coupons-create-edit-apply.cy.ts b/cypress/e2e/10-resources/t60-coupons-create-edit-apply.cy.ts index bcee83ac4..2ec37744f 100644 --- a/cypress/e2e/10-resources/t60-coupons-create-edit-apply.cy.ts +++ b/cypress/e2e/10-resources/t60-coupons-create-edit-apply.cy.ts @@ -3,47 +3,52 @@ import { customerName } from '../../support/reusableConstants' const couponName = `Coupon-${Math.round(Math.random() * 10000)}` describe('Coupons', () => { - it('should be able create a coupon with plan limitation', () => { - cy.visit('/coupons') - cy.get(`[data-test="add-coupon"]`).click() - cy.get('[data-test="submit"]').should('be.disabled') - cy.get('input[name="name"]').type(couponName) - cy.get('input[name="code"]').type(couponName) - cy.get('input[name="amountCents"]').type('30') - cy.get('[data-test="submit"]').should('be.enabled') + it('make sure file still exists', () => { + expect(true).to.equal(true) + }) - // Set plan limitation - cy.get('[data-test="checkbox-hasPlanOrBillableMetricLimit"]').click() - cy.get('[data-test="add-plan-limit"]').click() - cy.get('input[name="selectedPlan"]').click() - cy.get('[data-option-index="0"]').click() - cy.get('[data-test="submitAddPlanToCouponDialog"]').click() + // TODO: uncomment when CI e2e api setup is fixed + // it('should be able create a coupon with plan limitation', () => { + // cy.visit('/coupons') + // cy.get(`[data-test="add-coupon"]`).click() + // cy.get('[data-test="submit"]').should('be.disabled') + // cy.get('input[name="name"]').type(couponName) + // cy.get('input[name="code"]').type(couponName) + // cy.get('input[name="amountCents"]').type('30') + // cy.get('[data-test="submit"]').should('be.enabled') - // Submit form - cy.get('[data-test="submit"]').click() - cy.get(`[data-test="${couponName}"]`).should('exist') - }) + // // Set plan limitation + // cy.get('[data-test="checkbox-hasPlanOrBillableMetricLimit"]').click() + // cy.get('[data-test="add-plan-limit"]').click() + // cy.get('input[name="selectedPlan"]').click() + // cy.get('[data-option-index="0"]').click() + // cy.get('[data-test="submitAddPlanToCouponDialog"]').click() - it('should be able to edit the same coupon', () => { - cy.visit('/coupons') - cy.get(`[data-test="${couponName}"]`).click() - cy.get('[data-test="submit"]').should('be.disabled') - cy.get('[data-test="limited-plan-0"]').within(() => { - cy.get(`[data-test="delete-limited-plan-0"]`).click() - }) - cy.get('[data-test="limited-plan-0"]').should('not.exist') - cy.get('[data-test="add-plan-limit"]').click() - cy.get('input[name="selectedPlan"]').click() - cy.get('[data-option-index="0"]').click() - cy.get('[data-test="submitAddPlanToCouponDialog"]').click() - cy.get('[data-test="submit"]').should('be.disabled') - cy.get('input[name="amountCents"]').type('1') + // // Submit form + // cy.get('[data-test="submit"]').click() + // cy.get(`[data-test="${couponName}"]`).should('exist') + // }) + + // it('should be able to edit the same coupon', () => { + // cy.visit('/coupons') + // cy.get(`[data-test="${couponName}"]`).click() + // cy.get('[data-test="submit"]').should('be.disabled') + // cy.get('[data-test="limited-plan-0"]').within(() => { + // cy.get(`[data-test="delete-limited-plan-0"]`).click() + // }) + // cy.get('[data-test="limited-plan-0"]').should('not.exist') + // cy.get('[data-test="add-plan-limit"]').click() + // cy.get('input[name="selectedPlan"]').click() + // cy.get('[data-option-index="0"]').click() + // cy.get('[data-test="submitAddPlanToCouponDialog"]').click() + // cy.get('[data-test="submit"]').should('be.disabled') + // cy.get('input[name="amountCents"]').type('1') + + // cy.get('[data-test="submit"]').click() + // cy.get(`[data-test="${couponName}"]`).should('exist') + // }) - cy.get('[data-test="submit"]').click() - cy.get(`[data-test="${couponName}"]`).should('exist') - }) - // TODO: uncomment when CI e2e api setup is fixed // it('should be able to apply the coupon to a customer', () => { // cy.visit('/customers') // cy.get(`[data-test="${customerName}"]`).click() diff --git a/ditto/base.json b/ditto/base.json index ee731a3a3..9bbc5b043 100644 --- a/ditto/base.json +++ b/ditto/base.json @@ -235,28 +235,17 @@ "text_62b1edddbf5f461ab971277d": "Stripe", "text_62b1edddbf5f461ab9712795": "Payment provider", "text_62b1edddbf5f461ab97127ad": "Connected", - "text_62b1edddbf5f461ab971272b": "Connect to Stripe", - "text_62b1edddbf5f461ab9712739": "To connect to Stripe, please enter the API secret key associated with your Stripe account.", "text_62b1edddbf5f461ab9712748": "API secret key", "text_62b1edddbf5f461ab9712756": "Type an API secret key", "text_62b1edddbf5f461ab971276d": "Cancel", "text_62b1edddbf5f461ab9712773": "Connect to Stripe", "text_62b1edddbf5f461ab9712743": "Stripe API secret key successfully added", - "text_62b1edddbf5f461ab97126ee": "Stripe", "text_62b1edddbf5f461ab9712707": "Stripe", "text_62b1edddbf5f461ab971270d": "Connected", "text_62b1edddbf5f461ab971271f": "Payment provider", - "text_62b1edddbf5f461ab971273f": "API secret key", "text_62b1edddbf5f461ab9712787": "Edit", - "text_62b1edddbf5f461ab971279f": "Delete", - "text_62b1edddbf5f461ab971272d": "Edit Stripe API secret key", - "text_62b1edddbf5f461ab9712737": "By editing the API secret key, upcoming data will not be synchronised to the connected Stripe account.", - "text_62b1edddbf5f461ab9712754": "Type a new API secret key", "text_62b1edddbf5f461ab9712769": "Edit API secret key", "text_62b1edddbf5f461ab97126f6": "Stripe API secret key successfully edited", - "text_62b1edddbf5f461ab97126e4": "Delete Stripe API secret key", - "text_62b1edddbf5f461ab97126f0": "By deleting the API secret key, the existing connection will not be used anymore and upcoming data will not be synchronised to the connected Stripe account. Are you sure?", - "text_62b1edddbf5f461ab971270f": "Delete API secret key", "text_62b1edddbf5f461ab9712758": "Stripe API secret key successfully deleted", "text_62b328ead9a4caef81cd9c9c": "Default payment provider", "text_62b328ead9a4caef81cd9c9e": "Search or select a payment provider", @@ -698,7 +687,6 @@ "text_64639c4d172d7a006ef30514": "Tax rate", "text_64639c4d172d7a006ef30515": "Search or select a tax rate", "text_6499a4e4db5730004703f36b": "Fees from {{from}} to {{to}}", - "text_6499a6209ae0d900826053a7": "Due {{date}}", "text_645d071272418a14c1c76a77": "API key", "text_645d071272418a14c1c76a83": "Type an API key", "text_645d071272418a14c1c76a8f": "Merchant Account", @@ -707,7 +695,6 @@ "text_645d071272418a14c1c76ab0": "Type a Live prefix", "text_645d071272418a14c1c76aba": "HMAC Signature (optional)", "text_645d071272418a14c1c76ac4": "Type a HMAC Signature", - "text_649ab559e86bd6005ba9d725": "a one off invoice", "text_649e848fa4c023006e94ca32": "Coupon description (optional)", "text_649e85d35208d700473f79c9": "Describe your coupon", "text_64a6d736c23125004817627f": "Cancel subscription", @@ -783,8 +770,6 @@ "text_65281f686a80b400c8e2f6dd": "Overridden", "text_65281f686a80b400c8e2f6c3": "No active subscriptions", "text_65281f686a80b400c8e2f6c6": "Assign this plan to a customer to create an active subscription.", - "text_645d071272418a14c1c76a5f": "Connect to Adyen", - "text_645d071272418a14c1c76a6b": "To connect to Adyen, please enter the API key generated from your Adyen account and the Merchant Account.", "text_645d071272418a14c1c76ad8": "Connect to Adyen", "text_645d071272418a14c1c76a93": "Adyen connection successfully added", "text_645d071272418a14c1c76a6d": "Adyen", @@ -794,14 +779,10 @@ "text_645d071272418a14c1c76acc": "Live prefix (optional)", "text_645d071272418a14c1c76ae0": "HMAC Signature (optional)", "text_645d071272418a14c1c76a67": "Edit Adyen Connection", - "text_645d071272418a14c1c76a73": "By editing the API key or the Merchant Account, upcoming data will be synchronized to the newly connected Adyen account.", - "text_645d071272418a14c1c76adc": "Edit Adyen connection", "text_645d071272418a14c1c76a3e": "Adyen connection successfully edited", - "text_645d071272418a14c1c76a5d": "Delete Adyen connection", - "text_645d071272418a14c1c76a69": "By deleting this Adyen connection, the existing connection will not be used anymore and upcoming data will not be synchronized to the connected Adyen account. Are you sure?", "text_645d071272418a14c1c76a81": "Delete connection", "text_645d071272418a14c1c76b25": "Adyen connection successfully deleted", - "text_645d0728ea0a5a7bbf76d5c7": "Automatically create this customer in Adyen", + "text_645d0728ea0a5a7bbf76d5c7": "Create automatically this customer in Adyen", "text_645d0728ea0a5a7bbf76d5c9": "To ensure customer creation, their external ID must contain a minimum of 3 characters, and the payment registration must be completed using the checkout URL sent via webhook.", "text_63e27c56dfe64b846474ef0c": "Start now to share real-time information thanks to webhooks", "text_63ebaf555f88d954d73beb7e": "No webhook message here", @@ -1365,6 +1346,37 @@ "text_64b04d6b13f1cc00ab4bf6bf": "Available only for customers invoices in EUR currency", "text_64aeb7b998c4322918c84237": "Payment methods", "text_64aeb7b998c4322918c8423b": "Card & SEPA Direct Debit", + "text_6584550dc4cec7adf8615049": "Connect to Stripe", + "text_6584550dc4cec7adf861504b": "To connect to Stripe, please enter the API secret key associated with your Stripe account.", + "text_6584550dc4cec7adf861504d": "Connection name", + "text_6584550dc4cec7adf861504f": "Type a name", + "text_6584550dc4cec7adf8615051": "Connection code", + "text_6584550dc4cec7adf8615053": "Type a code", + "text_65845f35d7d69c3ab4793dac": "Edit connection", + "text_65845f35d7d69c3ab4793dad": "Delete connection", + "text_658461066530343fe1808cd7": "Delete connection to {{name}}", + "text_658461066530343fe1808cdb": "By deleting the connection, it will not be used anymore and upcoming data will not be synchronized to the connected Stripe account. Are you sure?", + "text_658461066530343fe1808cd9": "Edit connection to {{name}}", + "text_658461066530343fe1808cdd": "Edit information linked to this GoCardless connection.", + "text_658461066530343fe1808cc2": "By deleting the connection, it will not be used anymore and upcoming data will not be synchronized to the connected Adyen account. Are you sure?", + "text_65846181a741a1401ecdddb7": "By deleting the connection, it will not be used anymore and upcoming data will not be synchronized to the connected GoCardless account. Are you sure?\n\nTo fully remove this connection, please do it also in GoCardless.", + "text_659d5de7c9b7f51394f7f3fd": "Delete connection", + "text_658466afe6140b469140e1f9": "Finalize connection to GoCardless", + "text_658466afe6140b469140e1fb": "To finalize the connection with GoCardless, please enter an account name and a code.", + "text_658466afe6140b469140e207": "Connect to GoCardless", + "text_658466afe6140b469140e1fa": "Connect to Adyen", + "text_658466afe6140b469140e1fc": "To connect to Adyen, please enter the API key generated from your Adyen account and the Merchant Account.", + "text_65846763e6140b469140e235": "Add a connection", + "text_65846763e6140b469140e239": "Connected accounts", + "text_6584697bc905b246e70e5528": "Edit information linked to this Stripe connection.", + "text_65846a0ed9fdbd46c4afc42d": "Edit information linked to this Adyen connection.", + "text_658567dffff71e31ea5f0d33": "Reconnect via OAuth", + "text_658567dffff71e31ea5f0d3e": "Secret key", + "text_65940198687ce7b05cd62b61": "Connected account", + "text_65940198687ce7b05cd62b62": "Search or select a connected account", + "text_65940198687ce7b05cd62b63": "Please connect an Adyen account in the Settings -> Integration section", + "text_65940198687ce7b05cd62b64": "Please connect a Stripe account in the Settings -> Integration section", + "text_65940198687ce7b05cd62b65": "Please connect a Gocardless account in the Settings -> Integration section", "text_64c7a89b6c67eb6c98898167": "Net payment term", "text_64c7a89b6c67eb6c98898182": "Period within which a customer is expected to pay for an invoice after it has been issued.\nNeed more flexibility? Set a payment term at the customer level to override the one above.", "text_64c7a89b6c67eb6c988980eb": "The duration within which a customer is expected to remit payment after the invoice is issued. Note that it may impact all invoices already in draft.", @@ -1404,21 +1416,15 @@ "text_6566f920a1d6c35693d6ce0f": "Invoice numbering successfully edited", "text_6566f920a1d6c35693d6cd77": "10 char. maximum", "text_634ea0ecc6147de10ddb6625": "GoCardless", - "text_634ea0ecc6147de10ddb6629": "GoCardless", "text_634ea0ecc6147de10ddb662d": "Connected", "text_634ea0ecc6147de10ddb6631": "Payment provider", - "text_635bd8acb686f18909a57c87": "Reconnect", - "text_634ea0ecc6147de10ddb663d": "OAuth connection", - "text_634ea0ecc6147de10ddb6641": "Lago is connected to GoCardless via an OAuth connection. From Lago, you can only reconnect the two apps, to remove this connection, please do it in GoCardless.", "text_635bd8acb686f18909a57c93": "Use this secret key to set up webhooks in GoCardless", - "text_634ea0ecc6147de10ddb6645": "GoCardless successfully connected", - "text_634ea0ecc6147de10ddb6643": "Payment provider", "text_634ea0ecc6147de10ddb6646": "Connected", "text_634ea0ecc6147de10ddb6648": "GoCardless", "text_635bdbda84c98758f9bba8a0": "Connect Payment service provider in the Integrations section", - "text_635bdbda84c98758f9bba8aa": "Automatically create this customer in GoCardless", + "text_635bdbda84c98758f9bba8aa": "Create automatically this customer in GoCardless", "text_635bdbda84c98758f9bba8ae": "To ensure customer creation, you must fill in an email address, and the mandate registration must be completed using the checkout URL sent via webhook.", - "text_635bdbda84c98758f9bba89e": "Automatically create this customer in Stripe", + "text_635bdbda84c98758f9bba89e": "Create automatically this customer in Stripe", "text_6360ddae753a8b3e11c80c66": "Copy text", "text_6360ddae753a8b3e11c80c6c": "Secret key copied to clipboard", "text_636df520279a9e1b3c68cc67": "API keys & ID", @@ -1635,6 +1641,25 @@ "text_65269cd46e7ec037a6823fd6": "There are no voided invoices", "text_65269cd46e7ec037a6823fda": "You can void an invoice to mark it as non due. All voided invoices will be listed here", "text_65269cd46e7ec037a6823fd8": "This voided invoice cannot be found", + "text_659e67cd63512ef53284305a": "Minimum spend of {{amount}} prorated on days of usage", + "text_659e67cd63512ef532843070": "Fee per unit for the first {{toValue}}", + "text_659e67cd63512ef5328430af": "Fee per unit for the next {{fromValue}} to {{toValue}}", + "text_659e67cd63512ef5328430e6": "Fee per unit for {{fromValue}} and above", + "text_659e67cd63512ef53284310e": "Flat fee for the first {{toValue}}", + "text_659e67cd63512ef532843136": "Flat fee for the next {{fromValue}} to {{toValue}}", + "text_659e67cd63512ef53284314a": "Flat fee for {{fromValue}} and above", + "text_659e67cd63512ef532843154": "Subtotal", + "text_659e67cd63512ef532843078": "Fee per unit", + "text_659e67cd63512ef5328430b5": "Flat fee for all units", + "text_659e67cd63512ef53284303c": "Free units for the first {{freeUnits}}", + "text_659e67cd63512ef532843064": "Fee per package", + "text_659e67cd63512ef532843074": "{{perPackageUnitAmount}} per {{perPackageSize}}", + "text_659e67cd63512ef53284303e": "Total events: {{eventsCount}} transactions", + "text_659e67cd63512ef532843046": "Free units for {{freeEvents}} transactions|Free units for {{freeEvents}} transaction|Free units for {{freeEvents}} transactions", + "text_659e67cd63512ef53284306e": "Rate on the amount", + "text_659e67cd63512ef53284308f": "Fixed fee per transaction", + "text_659e67cd63512ef5328430ad": "Adjustment for min/max per transaction", + "text_659e6b6b8e57e6ff88a34930": "The fee is prorated on days of usage, the displayed unit price is an average", "text_6543ca0fdebf76a18e159294": "Edit default currency", "text_6543ca0fdebf76a18e159298": "This setting establishes a default currency for all object creations and for displaying the analytics page.", "text_6543ca0fdebf76a18e15929c": "Default currency", @@ -1666,7 +1691,6 @@ "text_65564e8e4af2340050d431be": "Insights", "text_65564e8e4af2340050d431bf": "Total monthly income, covering all financial aspects including taxes, discounts like credit notes, coupons, and credits, for an accurate financial overview.", "text_637f813d31381b1ed90ab315": "API Token", - "text_637f813d31381b1ed90ab322": "Copy key", "text_637f813d31381b1ed90ab30e": "This API secret key is used to connect Stripe to Lago, edit it to make a new connection", "text_637f813d31381b1ed90ab2f6": "API keys & ID", "text_637f813d31381b1ed90ab300": "Find all keys and IDs to connect Lago.", @@ -1735,8 +1759,6 @@ "text_634687079be251fdb43833fb": "Invoice number", "text_634687079be251fdb4383407": "Issuing date", "text_634687079be251fdb4383413": "Payment date", - "text_634d631acf4dce7b0127a39a": "{{invoiceDisplayName}} details", - "text_634d631acf4dce7b0127a3a0": "Total unit", "text_634d631acf4dce7b0127a3a6": "Amount", "text_634812d6f16b31ce5cbf4111": "Something went wrong", "text_634812d6f16b31ce5cbf411f": "Please refresh the page or contact us if the error persists.", @@ -1872,11 +1894,11 @@ "text_6391f05df4bf96d81f3660a7": "Credits", "text_637ccf8133d2c9a7d11ce70d": "Total amount due", "text_63887b52e514213fed57fc1c": "Total due", - "text_637cd81348c50c26dd05a767": "Credit note {{CreditNoteNumber}} on {{displayName}}", "text_637cd81348c50c26dd05a769": "Amount", "text_637ccf8133d2c9a7d11ce73d": "Credit subtotal (excl. tax)", "text_637ccf8133d2c9a7d11ce741": "Tax", "text_637ccf8133d2c9a7d11ce745": "Credit note total", + "text_659522c816b5850068729025": "Credit note {{CreditNoteNumber}}", "text_637de077dca2f885da839287": "Refund issued", "text_638f48274d41e3f1d01fc16a": "The coupon can be applied several times to the same customer", "text_638f48274d41e3f1d01fc119": "This coupon is not reusable and was already applied to {{customerFullName}}. Please apply another coupon.", diff --git a/ditto/config.yml b/ditto/config.yml index ce2b0c4dd..cbf1639a2 100644 --- a/ditto/config.yml +++ b/ditto/config.yml @@ -322,5 +322,10 @@ sources: fileName: 👍 [Ready for dev] - Settings - Define invoice number - name: ⚙️ [WIP] - Integration - Lago EU tax integration id: 657078becf8335e0955b5bf4 + fileName: ⚙️ [WIP] - Integration - Lago EU tax integration + - name: 👍 [Ready for dev] - Invoices - Display unit price to item in invoices + id: 659e67cc6afb842e8db57be5 + - name: 👍 [Ready for dev] - Settings - Several PSP Accounts + id: 6584550ac28443047853c17f format: flat variants: true diff --git a/ditto/index.js b/ditto/index.js index 3eefb9a71..0f7332151 100644 --- a/ditto/index.js +++ b/ditto/index.js @@ -53,6 +53,9 @@ module.exports = { "project_6543ca0b70910093c87cd539": { "base": require('./-ready-for-dev---dashboards---add-financial-reporting-to-lago__base.json') }, + "project_659e67cc6afb842e8db57be5": { + "base": require('./-ready-for-dev---invoices---display-unit-price-to-item-in-invoices__base.json') + }, "project_65269b3f720470569cb17228": { "base": require('./-ready-for-dev---invoices---void-invoices__base.json') }, @@ -104,6 +107,9 @@ module.exports = { "project_64c7a896197f1907cbc6371c": { "base": require('./-ready-for-dev---settings---net-payment-term__base.json') }, + "project_6584550ac28443047853c17f": { + "base": require('./-ready-for-dev---settings---several-psp-accounts__base.json') + }, "project_64aeb7b7d5628db33254c4bb": { "base": require('./-ready-for-dev---settings--customers---lago-x-stripe-sdd__base.json') }, diff --git a/package.json b/package.json index 82f9701f8..4096df9f8 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@testing-library/user-event": "^14.4.3", "@trivago/prettier-plugin-sort-imports": "^4.2.0", "@types/apollo-upload-client": "17.0.5", - "@types/jest": "29.5.10", + "@types/jest": "29.5.11", "@types/jsonwebtoken": "^9.0.2", "@types/lodash": "4.14.202", "@types/luxon": "3.3.1", @@ -58,7 +58,7 @@ "@types/react-router-dom": "5.3.3", "@types/react-window": "1.8.5", "@types/sanitize-html": "2.9.5", - "@types/styled-components": "5.1.32", + "@types/styled-components": "5.1.34", "@types/webpack": "5.28.2", "@typescript-eslint/eslint-plugin": "6.13.1", "@typescript-eslint/parser": "6.13.1", @@ -72,7 +72,7 @@ "duplicate-package-checker-webpack-plugin": "3.0.0", "eslint": "8.54.0", "eslint-config-prettier": "9.0.0", - "eslint-plugin-import": "2.29.0", + "eslint-plugin-import": "2.29.1", "eslint-plugin-jsx-a11y": "6.8.0", "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "4.6.0", diff --git a/src/components/customers/AddCustomerDrawer.tsx b/src/components/customers/AddCustomerDrawer.tsx index 7dcb1cd64..081e22c14 100644 --- a/src/components/customers/AddCustomerDrawer.tsx +++ b/src/components/customers/AddCustomerDrawer.tsx @@ -6,6 +6,7 @@ import React, { RefObject, useEffect, useImperativeHandle, + useMemo, useRef, useState, } from 'react' @@ -21,7 +22,13 @@ import { Tooltip, Typography, } from '~/components/designSystem' -import { Checkbox, ComboBoxField, Switch, TextInputField } from '~/components/form' +import { + BasicComboBoxData, + Checkbox, + ComboBoxField, + Switch, + TextInputField, +} from '~/components/form' import { hasDefinedGQLError } from '~/core/apolloClient' import { countryDataForCombobox } from '~/core/formats/countryDataForCombobox' import { INTEGRATIONS_ROUTE, ORGANIZATION_INFORMATIONS_ROUTE } from '~/core/router' @@ -47,8 +54,16 @@ import { useCurrentUser } from '~/hooks/useCurrentUser' import { useOrganizationInfos } from '~/hooks/useOrganizationInfos' import { Card, DrawerContent, DrawerSubmitButton, DrawerTitle, theme } from '~/styles' +import { ITEM_HEIGHT } from '../form/ComboBox/ComboBoxItem' + const MAX_METADATA_COUNT = 5 +const paymentProviderCodeEmptyTextLookup = { + [ProviderTypeEnum.Stripe]: 'text_65940198687ce7b05cd62b64', + [ProviderTypeEnum.Gocardless]: 'text_65940198687ce7b05cd62b65', + [ProviderTypeEnum.Adyen]: 'text_65940198687ce7b05cd62b63', +} + export interface AddCustomerDrawerRef { openDrawer: (customer?: AddCustomerDrawerFragment | null) => unknown closeDrawer: () => unknown @@ -71,9 +86,10 @@ export const AddCustomerDrawer = forwardRef((_, ref) => { const drawerRef = useRef(null) const [customer, setCustomer] = useState(null) const { isPremium } = useCurrentUser() - const { isEdition, onSave } = useCreateEditCustomer({ + const { isEdition, onSave, paymentProvidersList } = useCreateEditCustomer({ customer, }) + const [isDisabled, setIsDisabled] = useState(false) const formikProps = useFormik({ initialValues: { @@ -94,6 +110,7 @@ export const AddCustomerDrawer = forwardRef((_, ref) => { zipcode: customer?.zipcode ?? undefined, timezone: customer?.timezone ?? undefined, url: customer?.url ?? undefined, + paymentProviderCode: customer?.paymentProviderCode ?? undefined, providerCustomer: { providerCustomerId: customer?.providerCustomer?.providerCustomerId ?? undefined, syncWithProvider: customer?.providerCustomer?.syncWithProvider ?? false, @@ -111,6 +128,21 @@ export const AddCustomerDrawer = forwardRef((_, ref) => { email: string().email('text_620bc4d4269a55014d493fc3'), externalId: string().required(''), metadata: metadataSchema(), + providerCustomer: object().test({ + test: function (value, { from }) { + // Value can be undefined if no paymentProvider is selected + if (value && from && from[1] && !from[1].value.paymentProvider) { + return true + } + + // if code is not selected, validation fails + if (value && from && from[1] && !from[1].value.paymentProviderCode) { + return false + } + + return true + }, + }), }), validateOnMount: true, enableReinitialize: true, @@ -134,6 +166,28 @@ export const AddCustomerDrawer = forwardRef((_, ref) => { }, }) const { timezoneConfig } = useOrganizationInfos() + const connectedProvidersData: BasicComboBoxData[] | [] = useMemo(() => { + if (!paymentProvidersList || !formikProps.values.paymentProvider) return [] + const localProvider = paymentProvidersList[formikProps.values.paymentProvider] + + if (!localProvider) return [] + + return localProvider.map((provider) => ({ + value: provider.code, + label: provider.name, + labelNode: ( + + + {provider.name} + +   + + ({provider.code}) + + + ), + })) + }, [formikProps.values.paymentProvider, paymentProvidersList]) useEffect(() => { if (!formikProps.values.paymentProvider) { @@ -172,37 +226,7 @@ export const AddCustomerDrawer = forwardRef((_, ref) => { }, )} onClose={() => { - formikProps.resetForm({ - values: { - name: customer?.name ?? '', - externalId: customer?.externalId ?? '', - externalSalesforceId: customer?.externalSalesforceId ?? '', - legalName: customer?.legalName ?? undefined, - legalNumber: customer?.legalNumber ?? undefined, - taxIdentificationNumber: customer?.taxIdentificationNumber ?? undefined, - currency: customer?.currency ?? undefined, - phone: customer?.phone ?? undefined, - email: customer?.email ?? undefined, - url: customer?.url ?? undefined, - addressLine1: customer?.addressLine1 ?? undefined, - addressLine2: customer?.addressLine2 ?? undefined, - state: customer?.state ?? undefined, - country: customer?.country ?? undefined, - city: customer?.city ?? undefined, - zipcode: customer?.zipcode ?? undefined, - providerCustomer: { - providerCustomerId: customer?.providerCustomer?.providerCustomerId ?? undefined, - syncWithProvider: customer?.providerCustomer?.syncWithProvider ?? false, - providerPaymentMethods: customer?.providerCustomer?.providerPaymentMethods?.length - ? customer?.providerCustomer?.providerPaymentMethods - : customer?.currency !== CurrencyEnum.Eur - ? [ProviderPaymentMethodsEnum.Card] - : [ProviderPaymentMethodsEnum.Card, ProviderPaymentMethodsEnum.SepaDebit], - }, - paymentProvider: customer?.paymentProvider ?? undefined, - metadata: customer?.metadata ?? undefined, - }, - }) + formikProps.resetForm() formikProps.validateForm() }} > @@ -223,6 +247,8 @@ export const AddCustomerDrawer = forwardRef((_, ref) => { {translate('text_626c0c09812bbc00e4c59df1')} ((_, ref) => { /> {!!formikProps.values.paymentProvider && ( <> + ((_, ref) => { provider.value === formikProps.values.paymentProviderCode, + )?.label}` + : '' + }`} onChange={(e, checked) => { setIsDisabled(checked) formikProps.setFieldValue('providerCustomer.syncWithProvider', checked) @@ -728,4 +771,14 @@ const StripePaymentMethodWrapper = styled.div` } ` +const Item = styled.div` + min-height: ${ITEM_HEIGHT}px; + box-sizing: border-box; + display: flex; + align-items: center; + border-radius: 12px; + cursor: pointer; + box-sizing: border-box; +` + AddCustomerDrawer.displayName = 'AddCustomerDrawer' diff --git a/src/components/customers/CustomerMainInfos.tsx b/src/components/customers/CustomerMainInfos.tsx index 70acab31a..dd556305f 100644 --- a/src/components/customers/CustomerMainInfos.tsx +++ b/src/components/customers/CustomerMainInfos.tsx @@ -9,6 +9,7 @@ import { ProviderPaymentMethodsEnum, ProviderTypeEnum, TimezoneEnum, + useIntegrationsListForCustomerMainInfosQuery, } from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' import { theme } from '~/styles' @@ -35,6 +36,7 @@ gql` zipcode paymentProvider timezone + paymentProviderCode providerCustomer { id providerCustomerId @@ -46,6 +48,30 @@ gql` value } } + + query integrationsListForCustomerMainInfos($limit: Int) { + paymentProviders(limit: $limit) { + collection { + ... on StripeProvider { + id + name + code + } + + ... on GocardlessProvider { + id + name + code + } + + ... on AdyenProvider { + id + name + code + } + } + } + } ` interface CustomerMainInfosProps { @@ -56,6 +82,12 @@ interface CustomerMainInfosProps { export const CustomerMainInfos = ({ loading, customer, onEdit }: CustomerMainInfosProps) => { const { translate } = useInternationalization() + const { data } = useIntegrationsListForCustomerMainInfosQuery({ + variables: { limit: 1000 }, + }) + const linkedProvider = data?.paymentProviders?.collection?.find( + (provider) => provider?.code === customer?.paymentProviderCode, + ) if (loading || !customer) return ( @@ -207,6 +239,13 @@ export const CustomerMainInfos = ({ loading, customer, onEdit }: CustomerMainInf )} + {!!linkedProvider && ( +
+ {translate('text_65940198687ce7b05cd62b61')} + {linkedProvider?.name} + {linkedProvider?.code} +
+ )} {!!providerCustomer && !!providerCustomer?.providerCustomerId && (
{translate('text_62b5c912506c4905fa75524c')} diff --git a/src/components/designSystem/NavigationTab.tsx b/src/components/designSystem/NavigationTab.tsx index 4210d0d67..dd4af8145 100644 --- a/src/components/designSystem/NavigationTab.tsx +++ b/src/components/designSystem/NavigationTab.tsx @@ -133,21 +133,26 @@ const TabsBlock = styled.div<{ } } + /* Negative margin bellow allows to show the focus ring aroung buttons */ ${({ $align }) => $align === NavigationTabAlignEnum.left ? css` - padding: ${theme.spacing(4)} ${theme.spacing(12)}; + padding: ${theme.spacing(4)} ${theme.spacing(13)}; + margin: 0 -${theme.spacing(1)}; ${theme.breakpoints.down('sm')} { - padding: ${theme.spacing(4)}; + padding: ${theme.spacing(4)} ${theme.spacing(5)}; + margin: 0 -${theme.spacing(1)}; } ` : $align === NavigationTabAlignEnum.superLeft ? css` - padding: ${theme.spacing(4)} 0; + padding: ${theme.spacing(4)} ${theme.spacing(1)}; + margin: 0 -${theme.spacing(1)}; ${theme.breakpoints.down('sm')} { - padding: ${theme.spacing(4)}; + padding: ${theme.spacing(4)} ${theme.spacing(1)}; + margin: 0 -${theme.spacing(1)}; } ` : css` @@ -155,6 +160,11 @@ const TabsBlock = styled.div<{ flex: 1; } `} + + /* Prevent buttons to goes on multiple line */ + button div .MuiTypography-root { + white-space: nowrap; + } } &.navigation-tab--vertical { diff --git a/src/components/invoices/InvoiceCreditNotesTable.tsx b/src/components/invoices/InvoiceCreditNotesTable.tsx index d4d7bb5a2..7f098a513 100644 --- a/src/components/invoices/InvoiceCreditNotesTable.tsx +++ b/src/components/invoices/InvoiceCreditNotesTable.tsx @@ -9,7 +9,7 @@ import { CUSTOMER_INVOICE_CREDIT_NOTE_DETAILS_ROUTE } from '~/core/router' import { deserializeAmount } from '~/core/serializers/serializeAmount' import { CreditNote, CreditNoteItem, CurrencyEnum, FeeTypesEnum } from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' -import { NAV_HEIGHT, theme } from '~/styles' +import { theme } from '~/styles' gql` fragment InvoiceForCreditNotesTable on Invoice { @@ -105,40 +105,38 @@ export const InvoiceCreditNotesTable = memo( const subscription = subscriptionItem[0][0] ? subscriptionItem[0][0]?.fee.subscription : undefined - const creditNoteDisplayName = !!subscription - ? subscription?.name || - subscription.plan.invoiceDisplayName || - subscription?.plan?.name - : translate('text_649ab559e86bd6005ba9d725') + const creditNoteDisplayName = + subscription?.name || + subscription?.plan.invoiceDisplayName || + subscription?.plan?.name return ( - + @@ -164,7 +162,7 @@ export const InvoiceCreditNotesTable = memo( > - {loading ? ( - <> - {[1, 2, 3, 4].map((i) => ( - - - - - - ))} - - ) : ( - <> - {invoice.invoiceType !== InvoiceTypeEnum.Credit && ( - <> - {invoice.status !== InvoiceStatusTypeEnum.Draft && - !!Number(invoice?.couponsAmountCents) && - !isLegacyInvoice && ( - - - - - - )} - - - - - - {!!invoice.appliedTaxes?.length ? ( - <> - {invoice.appliedTaxes.map((appliedTax, i) => ( - - - - - - ))} - - ) : ( - - - - - - )} - - - - - - - )} - {!!Number(invoice?.creditNotesAmountCents) && ( - - - - - - )} - {invoice.status !== InvoiceStatusTypeEnum.Draft && - !!Number(invoice?.couponsAmountCents) && - !!isLegacyInvoice && ( - - - - - - )} - {invoice.status !== InvoiceStatusTypeEnum.Draft && - !!Number(invoice?.prepaidCreditAmountCents) && ( - - - - - - )} - - - - - - {invoice.status === InvoiceStatusTypeEnum.Draft && ( - - - - {translate('text_63b6f4e9b074e3b8beebb97f')} - - - )} - - )} - - ) - }, -) - -const RightSkeleton = styled(Skeleton)` - float: right; -` -const LoadingTR = styled.tr` - > td { - box-sizing: border-box; - padding: ${theme.spacing(3)} 0; - } -` - -const NoShadowTD = styled.td` - box-shadow: none !important; -` - -InvoiceDetailsTableFooter.displayName = 'InvoiceDetailsTableFooter' diff --git a/src/components/invoices/InvoiceDetailsTableHeader.tsx b/src/components/invoices/InvoiceDetailsTableHeader.tsx deleted file mode 100644 index b44ef0fdf..000000000 --- a/src/components/invoices/InvoiceDetailsTableHeader.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { memo } from 'react' - -import { Typography } from '~/components/designSystem' -import { useInternationalization } from '~/hooks/core/useInternationalization' - -interface InvoiceDetailsTableHeaderProps { - displayName?: string - period?: string - newFormat?: boolean -} - -export const InvoiceDetailsTableHeader = memo( - ({ displayName, period, newFormat }: InvoiceDetailsTableHeaderProps) => { - const { translate } = useInternationalization() - - return ( - - - - - {!!newFormat && ( - - )} - - - - - ) - }, -) - -InvoiceDetailsTableHeader.displayName = 'InvoiceDetailsTableHeader' diff --git a/src/components/invoices/details/InvoiceDetailsTable.tsx b/src/components/invoices/details/InvoiceDetailsTable.tsx new file mode 100644 index 000000000..390b33cc9 --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTable.tsx @@ -0,0 +1,465 @@ +import { gql } from '@apollo/client' +import React, { memo } from 'react' +import styled, { css } from 'styled-components' + +import { groupAndFormatFees, TExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' +import { formatDateToTZ } from '~/core/timezone' +import { + CurrencyEnum, + Customer, + FeeForInvoiceDetailsTableBodyLineFragmentDoc, + InvoiceForDetailsTableFooterFragmentDoc, + InvoiceForDetailsTableFragment, + InvoiceSubscription, + InvoiceSubscriptionFormatingFragmentDoc, + InvoiceTypeEnum, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' +import { theme } from '~/styles' + +import { InvoiceDetailsTableBodyLine } from './InvoiceDetailsTableBodyLine' +import { InvoiceDetailsTableFooter } from './InvoiceDetailsTableFooter' +import { InvoiceDetailsTableHeader } from './InvoiceDetailsTableHeader' +import { InvoiceDetailsTablePeriodLine } from './InvoiceDetailsTablePeriodLine' + +gql` + fragment FeeForInvoiceDetailsTable on Fee { + id + amountCents + description + feeType + groupName + invoiceDisplayName + invoiceName + itemName + units + preciseUnitAmount + appliedTaxes { + id + taxRate + } + trueUpFee { + id + } + trueUpParentFee { + id + } + charge { + id + payInAdvance + invoiceDisplayName + billableMetric { + id + name + aggregationType + } + } + group { + id + key + value + } + + ...FeeForInvoiceDetailsTableBodyLine + } + + fragment InvoiceForDetailsTable on Invoice { + invoiceType + subTotalExcludingTaxesAmountCents + subTotalIncludingTaxesAmountCents + totalAmountCents + currency + issuingDate + versionNumber + + fees { + id + ...FeeForInvoiceDetailsTable + } + customer { + id + currency + applicableTimezone + } + invoiceSubscriptions { + fromDatetime + toDatetime + chargesFromDatetime + chargesToDatetime + inAdvanceChargesFromDatetime + inAdvanceChargesToDatetime + subscription { + id + name + plan { + id + name + interval + amountCents + amountCurrency + invoiceDisplayName + } + } + fees { + id + subscription { + id + name + plan { + id + name + invoiceDisplayName + } + } + ...FeeForInvoiceDetailsTable + } + + ...InvoiceSubscriptionFormating + } + + ...InvoiceForDetailsTableFooter + } + + ${InvoiceSubscriptionFormatingFragmentDoc} + ${InvoiceForDetailsTableFooterFragmentDoc} + ${FeeForInvoiceDetailsTableBodyLineFragmentDoc} +` + +interface InvoiceDetailsTableProps { + customer: Customer + invoice: InvoiceForDetailsTableFragment +} + +export const InvoiceDetailsTable = memo(({ customer, invoice }: InvoiceDetailsTableProps) => { + const { translate } = useInternationalization() + const currency = invoice?.currency || CurrencyEnum.Usd + const canHaveUnitPrice = invoice.versionNumber >= 4 + + /****************** + * One-off invoice + ******************/ + if ( + [InvoiceTypeEnum.AddOn, InvoiceTypeEnum.Credit, InvoiceTypeEnum.OneOff].includes( + invoice.invoiceType, + ) + ) { + return ( + +
- + - + {translate('text_636bedf292786b19d3398f06')} - + {translate('text_637cd81348c50c26dd05a769')}
- + {groupDimension === 0 ? ( <> {item?.fee?.feeType === FeeTypesEnum.AddOn @@ -427,84 +425,63 @@ const Wrapper = styled.section` > thead > tr > th, > tbody > tr > td { overflow: hidden; - line-break: anywhere; + text-align: right; - &:nth-child(1) { - width: 70%; + &:not(:first-child) { + line-break: anywhere; } - &:nth-child(2) { - width: 10%; - } - &:nth-child(3) { - width: 20%; + + &:not(:last-child) { + padding-right: ${theme.spacing(8)}; + box-sizing: border-box; } - } - > tfoot > tr > td { &:nth-child(1) { - width: 50%; + width: 75%; + text-align: left; } &:nth-child(2) { - width: 35%; + width: 10%; } &:nth-child(3) { width: 15%; } } - > tfoot > tr > td { - &:nth-child(2) { - text-align: left; - } - } - - th:not(:last-child), - td:not(:last-child) { - padding-right: ${theme.spacing(3)}; + > thead > tr > th { + position: sticky; + top: 72px; + background-color: ${theme.palette.common.white}; + padding: ${theme.spacing(8)} 0 ${theme.spacing(3)} 0; + box-sizing: border-box; + box-shadow: ${theme.shadows[7]}; } - > thead > tr > th, > tbody > tr > td { - text-align: right; - - &:first-child { - text-align: left; - } + vertical-align: top; + min-height: 44px; + padding: ${theme.spacing(3)} 0; + box-sizing: border-box; + box-shadow: ${theme.shadows[7]}; } > tfoot > tr > td { text-align: right; padding: ${theme.spacing(3)} 0; - } + box-sizing: border-box; - > tfoot > tr > td { - &:nth-child(2), + &:nth-child(1) { + width: 50%; + } + &:nth-child(2) { + width: 35%; + text-align: left; + box-shadow: ${theme.shadows[7]}; + } &:nth-child(3) { + width: 15%; box-shadow: ${theme.shadows[7]}; } } - - > thead > tr { - height: ${NAV_HEIGHT}px; - box-shadow: ${theme.shadows[7]}; - } - - > thead > tr > th { - height: ${NAV_HEIGHT}px; - box-sizing: border-box; - padding: ${theme.spacing(8)} 0 ${theme.spacing(3)} 0; - } - - > tbody > tr > td { - vertical-align: top; - min-height: 44px; - padding: ${theme.spacing(3)} 0; - box-shadow: ${theme.shadows[7]}; - } } ` - -const InlineTh = styled.th` - display: flex; - align-items: center; -` diff --git a/src/components/invoices/InvoiceCustomerInfos.tsx b/src/components/invoices/InvoiceCustomerInfos.tsx index e56a51f2f..bd4db404a 100644 --- a/src/components/invoices/InvoiceCustomerInfos.tsx +++ b/src/components/invoices/InvoiceCustomerInfos.tsx @@ -265,18 +265,13 @@ InvoiceCustomerInfos.displayName = 'InvoiceCustomerInfos' const Wrapper = styled.section` padding: ${theme.spacing(6)} 0; box-shadow: ${theme.shadows[7]}; - display: flex; - - > * { - flex: 1; - } - - > div:first-child > div > *:last-child { - padding-right: ${theme.spacing(8)}; - } + display: grid; + grid-template-columns: 1fr 1fr; + gap: ${theme.spacing(8)}; ${theme.breakpoints.down('md')} { - flex-direction: column; + grid-template-columns: 1fr; + gap: initial; } ` diff --git a/src/components/invoices/InvoiceDetailsTable.tsx b/src/components/invoices/InvoiceDetailsTable.tsx deleted file mode 100644 index 309e9c661..000000000 --- a/src/components/invoices/InvoiceDetailsTable.tsx +++ /dev/null @@ -1,711 +0,0 @@ -import { gql } from '@apollo/client' -import React, { memo } from 'react' -import styled from 'styled-components' - -import { Skeleton, Typography } from '~/components/designSystem' -import formatInvoiceItemsMap from '~/core/formats/formatInvoiceItemsMap' -import { intlFormatNumber } from '~/core/formats/intlFormatNumber' -import { deserializeAmount } from '~/core/serializers/serializeAmount' -import { formatDateToTZ } from '~/core/timezone' -import { - CurrencyEnum, - Customer, - Invoice, - InvoiceForDetailsTableFeeFragmentDoc, - InvoiceForDetailsTableFooterFragmentDoc, - InvoiceSubscription, - InvoiceTypeEnum, - Subscription, -} from '~/generated/graphql' -import { useInternationalization } from '~/hooks/core/useInternationalization' -import { NAV_HEIGHT, theme } from '~/styles' - -import { InvoiceDetailsTableFeeItem } from './InvoiceDetailsTableFeeItem' -import { InvoiceDetailsTableFooter } from './InvoiceDetailsTableFooter' -import { InvoiceDetailsTableHeader } from './InvoiceDetailsTableHeader' - -gql` - fragment FeeForInvoiceDetailsTable on Fee { - id - amountCents - description - feeType - groupName - invoiceDisplayName - invoiceName - itemName - units - preciseUnitAmount - appliedTaxes { - id - taxRate - } - trueUpFee { - id - } - trueUpParentFee { - id - } - charge { - id - payInAdvance - invoiceDisplayName - billableMetric { - id - name - aggregationType - } - } - group { - id - key - value - } - } - - fragment InvoiceForDetailsTable on Invoice { - invoiceType - subTotalExcludingTaxesAmountCents - subTotalIncludingTaxesAmountCents - totalAmountCents - currency - issuingDate - - ...InvoiceForDetailsTableFee - ...InvoiceForDetailsTableFooter - - fees { - id - ...FeeForInvoiceDetailsTable - } - customer { - id - currency - applicableTimezone - } - invoiceSubscriptions { - fromDatetime - toDatetime - chargesFromDatetime - chargesToDatetime - inAdvanceChargesFromDatetime - inAdvanceChargesToDatetime - subscription { - id - name - plan { - id - name - interval - amountCents - amountCurrency - invoiceDisplayName - } - } - fees { - id - subscription { - id - name - plan { - id - name - invoiceDisplayName - } - } - ...FeeForInvoiceDetailsTable - } - } - } - - ${InvoiceForDetailsTableFeeFragmentDoc} - ${InvoiceForDetailsTableFooterFragmentDoc} -` - -interface InvoiceDetailsTableProps { - customer: Customer - invoice: Invoice - loading: boolean -} - -const getSubscriptionDisplayName = (subscription: Subscription) => { - if (!!subscription.name) { - return subscription.name - } else if (!!subscription.plan?.invoiceDisplayName) { - return subscription.plan.invoiceDisplayName - } - - const plan = subscription?.plan - const planInterval = `${plan?.interval?.charAt(0)?.toUpperCase()}${plan?.interval?.slice(1)}` - - return `${planInterval} - ${plan?.name}` -} - -export const InvoiceDetailsTable = memo( - ({ customer, invoice, loading }: InvoiceDetailsTableProps) => { - const { translate } = useInternationalization() - const currency = invoice?.currency || CurrencyEnum.Usd - - if ( - [InvoiceTypeEnum.AddOn, InvoiceTypeEnum.Credit, InvoiceTypeEnum.OneOff].includes( - invoice.invoiceType, - ) - ) { - return ( - - - - - - {invoice.fees?.map((fee, i) => ( - - - - - - - - ))} - -
- - {invoice.invoiceType === InvoiceTypeEnum.AddOn - ? translate('text_6388baa2e514213fed583611', { name: fee.itemName }) - : invoice.invoiceType === InvoiceTypeEnum.OneOff - ? fee.invoiceDisplayName || fee.itemName - : translate('text_637ccf8133d2c9a7d11ce6e1')} - - {!!fee.description && ( - - {fee.description} - - )} - - - {fee.units} - - - - {intlFormatNumber(fee.preciseUnitAmount || 0, { - currencyDisplay: 'symbol', - currency, - })} - - - - {fee.appliedTaxes?.length - ? fee.appliedTaxes.map((appliedTaxes) => ( - - {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { - maximumFractionDigits: 2, - style: 'percent', - })} - - )) - : '0%'} - - - - {intlFormatNumber(deserializeAmount(fee.amountCents || 0, currency), { - currencyDisplay: 'symbol', - currency, - })} - -
- - -
-
- ) - } - - const formattedInvoiceItemsMap = formatInvoiceItemsMap( - invoice?.invoiceSubscriptions as InvoiceSubscription[], - ) - - return ( - - {formattedInvoiceItemsMap.map( - ( - { - invoiceSubscription, - currentSubscription, - invoiceDisplayName, - subscriptionFees, - feesInArrears, - feesInAdvance, - }, - i, - ) => { - const hasAnySubscriptionFeeUnits = subscriptionFees?.some( - (fee) => Number(fee.units) > 0, - ) - const hasAnyArrearsFeeUnits = feesInArrears?.some((fee) => Number(fee.units) > 0) - const hasAnyAdvanceFeeUnits = feesInAdvance?.some((fee) => Number(fee.units) > 0) - - return ( - - - r.units === 0) && - !hasAnyAdvanceFeeUnits - ? invoiceSubscription?.chargesFromDatetime && - invoiceSubscription?.chargesToDatetime - ? translate('text_6499a4e4db5730004703f36b', { - from: formatDateToTZ( - invoiceSubscription?.chargesFromDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - to: formatDateToTZ( - invoiceSubscription?.chargesToDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - }) - : translate('text_6499a6209ae0d900826053a7', { - date: formatDateToTZ( - invoice.issuingDate, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - }) - : !hasAnySubscriptionFeeUnits && - !hasAnyArrearsFeeUnits && - !hasAnyAdvanceFeeUnits && - !!invoiceSubscription?.fromDatetime && - !!invoiceSubscription?.toDatetime - ? translate('text_6499a4e4db5730004703f36b', { - from: formatDateToTZ( - invoiceSubscription?.fromDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - to: formatDateToTZ( - invoiceSubscription?.toDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - }) - : undefined - } - /> -
- - {/* If no positive fees are present in the invoice, display subscription fee placeholder */} - {!hasAnySubscriptionFeeUnits && - !hasAnyArrearsFeeUnits && - // Same condition as bellow to show/hide fees in advance - !feesInAdvance?.some( - (fee) => !(Number(fee?.units) === 0 && !!fee?.isGroupChildFee), - ) && ( - - - - - - - - - -
- - {getSubscriptionDisplayName(currentSubscription)} - - - - 0 - - - - 0% - - - - {intlFormatNumber(0, { - currencyDisplay: 'symbol', - currency, - })} - -
- )} - {subscriptionFees?.map((fee, j) => { - return ( - - - - - - - - - -
- - {getSubscriptionDisplayName(currentSubscription)} - - - - 1 - - - - {fee.appliedTaxes?.length - ? fee.appliedTaxes.map((appliedTaxes) => ( - - {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { - maximumFractionDigits: 2, - style: 'percent', - })} - - )) - : '0%'} - - - - {intlFormatNumber(deserializeAmount(fee.amountCents || 0, currency), { - currencyDisplay: 'symbol', - currency, - })} - -
- ) - })} - {((hasAnySubscriptionFeeUnits && hasAnyArrearsFeeUnits) || - feesInArrears.some((r) => r.units !== 0 || !r.isGroupChildFee)) && ( - - {invoiceSubscription?.chargesFromDatetime && - invoiceSubscription?.chargesToDatetime - ? translate('text_6499a4e4db5730004703f36b', { - from: formatDateToTZ( - invoiceSubscription?.chargesFromDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - to: formatDateToTZ( - invoiceSubscription?.chargesToDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - }) - : translate('text_6499a6209ae0d900826053a7', { - date: formatDateToTZ( - invoice.issuingDate, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - })} - - )} - {feesInArrears.map((fee, j) => { - if (Number(fee?.units) === 0) return - - { - !!loading && ( - - - {[1, 2, 3].map((k) => ( - - - - - - - ))} - -
- - - - - - - -
- ) - } - - return ( - - ) - })} - {/* Charge paid in advance */} - {!!hasAnyAdvanceFeeUnits && ( - - {invoiceSubscription?.inAdvanceChargesFromDatetime && - invoiceSubscription?.inAdvanceChargesToDatetime - ? translate('text_6499a4e4db5730004703f36b', { - from: formatDateToTZ( - invoiceSubscription?.inAdvanceChargesFromDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - to: formatDateToTZ( - invoiceSubscription?.inAdvanceChargesToDatetime, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - }) - : translate('text_6499a6209ae0d900826053a7', { - date: formatDateToTZ( - invoice.issuingDate, - customer?.applicableTimezone, - 'LLL. dd, yyyy', - ), - })} - - )} - {feesInAdvance.map((fee) => { - if (Number(fee?.units) === 0 && !!fee?.isGroupChildFee) return - - return ( - - ) - })} -
- ) - }, - )} - - -
-
- ) - }, -) - -InvoiceDetailsTable.displayName = 'InvoiceDetailsTable' - -const InvoiceWrapper = styled.section` - > table { - width: 100%; - border-collapse: collapse; - table-layout: fixed; - - > thead > tr > th, - > tbody > tr > td { - overflow: hidden; - line-break: anywhere; - - &:nth-child(1) { - width: 50%; - } - &:nth-child(2) { - width: 10%; - } - &:nth-child(3) { - width: 15%; - } - &:nth-child(4) { - width: 10%; - } - &:nth-child(5) { - width: 15%; - } - } - - > tfoot > tr > td { - &:nth-child(1) { - width: 50%; - } - &:nth-child(2) { - width: 35%; - } - &:nth-child(3) { - width: 15%; - } - } - - > tfoot > tr > td { - &:nth-child(2) { - text-align: left; - } - } - - th:not(:last-child), - td:not(:last-child) { - padding-right: ${theme.spacing(3)}; - box-sizing: border-box; - } - - > thead > tr > th, - > tbody > tr > td { - text-align: right; - - &:nth-child(1) { - text-align: left; - } - } - - > tfoot > tr > td { - text-align: right; - padding: ${theme.spacing(3)} 0; - box-sizing: border-box; - } - - > tfoot > tr > td { - &:nth-child(2), - &:nth-child(3) { - box-shadow: ${theme.shadows[7]}; - } - } - - > thead > tr > th { - height: ${NAV_HEIGHT}px; - padding: ${theme.spacing(8)} 0 ${theme.spacing(3)} 0; - box-sizing: border-box; - box-shadow: ${theme.shadows[7]}; - } - - > tbody > tr > td { - vertical-align: top; - min-height: 44px; - padding: ${theme.spacing(3)} 0; - box-sizing: border-box; - box-shadow: ${theme.shadows[7]}; - } - } -` - -const Wrapper = styled.section` - > table { - width: 100%; - border-collapse: collapse; - table-layout: fixed; - - > thead > tr > th, - > tbody > tr > td { - overflow: hidden; - line-break: anywhere; - - &:nth-child(1) { - width: 50%; - } - &:nth-child(2) { - width: 20%; - } - &:nth-child(3) { - width: 10%; - } - &:nth-child(4) { - width: 20%; - } - } - - > tfoot > tr > td { - &:nth-child(1) { - width: 50%; - } - &:nth-child(2) { - width: 35%; - } - &:nth-child(3) { - width: 15%; - } - } - - > tfoot > tr > td { - &:nth-child(2) { - text-align: left; - } - } - - th:not(:last-child), - td:not(:last-child) { - padding-right: ${theme.spacing(3)}; - box-sizing: border-box; - } - - > thead > tr > th, - > tbody > tr > td { - text-align: right; - - &:nth-child(1), - &:nth-child(2) { - text-align: left; - } - } - - > tfoot > tr > td { - text-align: right; - padding: ${theme.spacing(3)} 0; - box-sizing: border-box; - } - - > tfoot > tr > td { - &:nth-child(2), - &:nth-child(3) { - box-shadow: ${theme.shadows[7]}; - } - } - - > thead > tr > th { - height: ${NAV_HEIGHT}px; - padding: ${theme.spacing(8)} 0 ${theme.spacing(3)} 0; - box-sizing: border-box; - box-shadow: ${theme.shadows[7]}; - } - - > tbody > tr > td { - vertical-align: top; - min-height: 44px; - padding: ${theme.spacing(3)} 0; - box-sizing: border-box; - box-shadow: ${theme.shadows[7]}; - } - } -` - -const RightSkeleton = styled(Skeleton)` - float: right; -` - -const ChargePeriodSeparator = styled(Typography)` - padding: ${theme.spacing(3)} 0; - box-sizing: border-box; - box-shadow: ${theme.shadows[7]}; -` diff --git a/src/components/invoices/InvoiceDetailsTableFeeItem.tsx b/src/components/invoices/InvoiceDetailsTableFeeItem.tsx deleted file mode 100644 index 7b21b8371..000000000 --- a/src/components/invoices/InvoiceDetailsTableFeeItem.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import { gql } from '@apollo/client' -import React, { memo } from 'react' - -import { Typography } from '~/components/designSystem' -import { ExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' -import { intlFormatNumber } from '~/core/formats/intlFormatNumber' -import { deserializeAmount } from '~/core/serializers/serializeAmount' -import { - CurrencyEnum, - Customer, - InvoiceForDetailsTableFooterFragmentDoc, -} from '~/generated/graphql' -import { useInternationalization } from '~/hooks/core/useInternationalization' - -gql` - fragment InvoiceForDetailsTableFee on Invoice { - invoiceType - subTotalExcludingTaxesAmountCents - subTotalIncludingTaxesAmountCents - totalAmountCents - currency - issuingDate - - ...InvoiceForDetailsTableFooter - - fees { - id - amountCents - itemName - units - feeType - invoiceDisplayName - appliedTaxes { - id - taxRate - } - trueUpFee { - id - } - charge { - id - payInAdvance - } - } - customer { - id - currency - applicableTimezone - } - invoiceSubscriptions { - fromDatetime - toDatetime - chargesFromDatetime - chargesToDatetime - inAdvanceChargesFromDatetime - inAdvanceChargesToDatetime - subscription { - id - name - plan { - id - name - interval - amountCents - amountCurrency - } - } - fees { - id - amountCents - eventsCount - units - feeType - invoiceDisplayName - groupName - appliedTaxes { - id - taxRate - } - trueUpFee { - id - } - trueUpParentFee { - id - } - charge { - id - payInAdvance - billableMetric { - id - name - aggregationType - } - } - group { - id - key - value - } - } - } - } - - ${InvoiceForDetailsTableFooterFragmentDoc} -` - -interface InvoiceDetailsTableFeeItemProps { - currency: CurrencyEnum - customer: Customer - fee: ExtendedRemainingFee - invoiceSubscriptionIndex: number - label?: string - units?: number -} - -export const InvoiceDetailsTableFeeItem = memo( - ({ customer, fee, invoiceSubscriptionIndex, label, units }: InvoiceDetailsTableFeeItemProps) => { - const { translate } = useInternationalization() - - return ( - - - - - - - - - -
- - {!!label ? ( - <>{label} - ) : ( - <> - {fee.displayName} - {!!fee.isTrueUpFee ? ` - ${translate('text_64463aaa34904c00a23be4f7')}` : ''} - - )} - - - - {!!units ? units : fee.units} - - - - {fee.appliedTaxes?.length - ? fee.appliedTaxes.map((appliedTaxes) => ( - - {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { - maximumFractionDigits: 2, - style: 'percent', - })} - - )) - : '0%'} - - - { - - {intlFormatNumber( - deserializeAmount(fee.amountCents || 0, customer?.currency || CurrencyEnum.Usd), - { - currencyDisplay: 'symbol', - currency: customer?.currency || CurrencyEnum.Usd, - }, - )} - - } -
- ) - }, -) - -InvoiceDetailsTableFeeItem.displayName = 'InvoiceDetailsTableFeeItem' diff --git a/src/components/invoices/InvoiceDetailsTableFooter.tsx b/src/components/invoices/InvoiceDetailsTableFooter.tsx deleted file mode 100644 index 98975ecf5..000000000 --- a/src/components/invoices/InvoiceDetailsTableFooter.tsx +++ /dev/null @@ -1,325 +0,0 @@ -import { gql } from '@apollo/client' -import { memo } from 'react' -import styled from 'styled-components' - -import { Alert, Skeleton, Typography } from '~/components/designSystem' -import { intlFormatNumber } from '~/core/formats/intlFormatNumber' -import { deserializeAmount } from '~/core/serializers/serializeAmount' -import { CurrencyEnum, Invoice, InvoiceStatusTypeEnum, InvoiceTypeEnum } from '~/generated/graphql' -import { useInternationalization } from '~/hooks/core/useInternationalization' -import { theme } from '~/styles' - -gql` - fragment InvoiceForDetailsTableFooter on Invoice { - couponsAmountCents - creditNotesAmountCents - subTotalExcludingTaxesAmountCents - subTotalIncludingTaxesAmountCents - totalAmountCents - currency - prepaidCreditAmountCents - versionNumber - appliedTaxes { - id - amountCents - feesAmountCents - taxRate - taxName - } - } -` - -interface InvoiceDetailsTableFooterProps { - invoice: Invoice - loading: boolean - newFormat?: boolean -} - -export const InvoiceDetailsTableFooter = memo( - ({ invoice, loading, newFormat }: InvoiceDetailsTableFooterProps) => { - const { translate } = useInternationalization() - const currency = invoice?.currency || CurrencyEnum.Usd - const isLegacyInvoice = invoice?.versionNumber < 3 - - return ( -
- - - -
- - {translate('text_637ccf8133d2c9a7d11ce705')} - - - - - - {intlFormatNumber( - deserializeAmount(invoice?.couponsAmountCents || 0, currency), - { - currencyDisplay: 'symbol', - currency, - }, - )} - -
- - {translate('text_637ccf8133d2c9a7d11ce6f9')} - - - - {intlFormatNumber( - deserializeAmount( - invoice?.subTotalExcludingTaxesAmountCents || 0, - currency, - ), - { - currencyDisplay: 'symbol', - currency, - }, - )} - -
- - {translate('text_64c013a424ce2f00dffb7f4d', { - name: appliedTax.taxName, - rate: intlFormatNumber(appliedTax.taxRate / 100 || 0, { - maximumFractionDigits: 2, - style: 'percent', - }), - amount: intlFormatNumber( - deserializeAmount(appliedTax.feesAmountCents || 0, currency), - { - currencyDisplay: 'symbol', - currency, - }, - ), - })} - - - - {intlFormatNumber( - deserializeAmount(appliedTax.amountCents || 0, currency), - { - currencyDisplay: 'symbol', - currency, - }, - )} - -
- - {`${translate('text_637ccf8133d2c9a7d11ce6fd')} (0%)`} - - - - {intlFormatNumber(0, { - currencyDisplay: 'symbol', - currency, - })} - -
- - {translate('text_637ccf8133d2c9a7d11ce701')} - - - - {intlFormatNumber( - deserializeAmount( - invoice?.subTotalIncludingTaxesAmountCents || 0, - currency, - ), - { - currencyDisplay: 'symbol', - currency, - }, - )} - -
- - {translate('text_637ccf8133d2c9a7d11ce708')} - - - - - - {intlFormatNumber( - deserializeAmount(invoice?.creditNotesAmountCents || 0, currency), - { - currencyDisplay: 'symbol', - currency, - }, - )} - -
- - {translate('text_637ccf8133d2c9a7d11ce705')} - - - - - - {intlFormatNumber( - deserializeAmount(invoice?.couponsAmountCents || 0, currency), - { - currencyDisplay: 'symbol', - currency, - }, - )} - -
- - {translate('text_6391f05df4bf96d81f3660a7')} - - - - - - {intlFormatNumber( - deserializeAmount(invoice?.prepaidCreditAmountCents || 0, currency), - { - currencyDisplay: 'symbol', - currency, - }, - )} - -
- - {invoice.invoiceType === InvoiceTypeEnum.Credit - ? translate('text_63887b52e514213fed57fc1c') - : translate('text_637ccf8133d2c9a7d11ce70d')} - - - - {intlFormatNumber(deserializeAmount(invoice?.totalAmountCents || 0, currency), { - currencyDisplay: 'symbol', - currency, - })} - -
- {!!displayName && ( - - {displayName} - - )} - {!!period && ( - - {period} - - )} - - - {translate( - newFormat ? 'text_65771fa3f4ab9a00720726ce' : 'text_634d631acf4dce7b0127a3a0', - )} - - - - {translate('text_6453819268763979024ad089')} - - - - {translate('text_636bedf292786b19d3398f06')} - - - - {translate('text_634d631acf4dce7b0127a3a6')} - -
+ + + {invoice.fees?.map((fee, i) => ( + + ))} + + +
+ + ) + } + + const newFormattedInvoiceItemsMap = groupAndFormatFees( + invoice?.invoiceSubscriptions as InvoiceSubscription[], + ) + + /********************* + * No fee placeholder + *********************/ + if (!newFormattedInvoiceItemsMap?.metadata?.hasAnyFeeParsed) { + return ( + <> + {Object.entries(newFormattedInvoiceItemsMap.subscriptions).map( + ([subscriptionId, subscription]) => { + return ( + + + + + + + + + + +
+
+ ) + }, + )} + + ) + } + + /************* + * Other fees + *************/ + return ( + + + {Object.entries(newFormattedInvoiceItemsMap.subscriptions).map( + ([subscriptionId, subscription]) => { + return ( + + + + {/* Arrears */} + {subscription.feesInArrears.length > 0 && ( + <> + + {subscription.feesInArrears.map((feeInArrear) => { + return ( + + ) + })} + + )} + {/* Advance */} + {subscription.feesInAdvance.length > 0 && ( + <> + + {subscription.feesInAdvance.map((feeInAdvance) => { + return ( + + ) + })} + + )} + +
+ ) + }, + )} + + {/* Footer */} + + +
+
+
+ ) +}) + +InvoiceDetailsTable.displayName = 'InvoiceDetailsTable' + +export const InvoiceWrapper = styled.section<{ $canHaveUnitPrice: boolean }>` + table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; + + thead tr th, + tbody tr td { + overflow: hidden; + text-align: right; + + &:not(:first-child) { + line-break: anywhere; + } + + &:not(:last-child) { + padding-right: ${theme.spacing(8)}; + box-sizing: border-box; + } + + ${({ $canHaveUnitPrice }) => + $canHaveUnitPrice + ? css` + &:nth-child(1) { + width: 50%; + text-align: left; + } + &:nth-child(2) { + width: 10%; + } + &:nth-child(3) { + width: 15%; + } + &:nth-child(4) { + width: 10%; + } + &:nth-child(5) { + width: 15%; + } + ` + : css` + &:nth-child(1) { + width: 50%; + text-align: left; + } + &:nth-child(2) { + width: 20%; + } + &:nth-child(3) { + width: 10%; + } + &:nth-child(4) { + width: 20%; + } + `}; + } + + thead tr th { + position: sticky; + top: 72px; + background-color: ${theme.palette.common.white}; + z-index: 1; + padding: ${theme.spacing(8)} 0 ${theme.spacing(3)} 0; + box-sizing: border-box; + box-shadow: ${theme.shadows[7]}; + } + + tbody tr { + td { + vertical-align: top; + min-height: 44px; + padding: ${theme.spacing(3)} 0; + box-sizing: border-box; + box-shadow: ${theme.shadows[7]}; + } + + &.has-details td { + min-height: 24px; + padding: ${theme.spacing(3)} ${theme.spacing(8)} ${theme.spacing(1)} 0; + box-shadow: none; + } + + &.details-line td { + vertical-align: top; + min-height: 24px; + padding: ${theme.spacing(1)} ${theme.spacing(8)} ${theme.spacing(1)} ${theme.spacing(4)}; + box-sizing: border-box; + box-shadow: initial; + + &:last-child { + padding-right: 0; + } + } + + &.subtotal td { + box-shadow: ${theme.shadows[7]}; + padding: ${theme.spacing(1)} ${theme.spacing(8)} ${theme.spacing(3)} ${theme.spacing(4)}; + &:last-child { + padding-right: 0; + } + } + } + + tfoot tr td { + text-align: right; + padding: ${theme.spacing(3)} 0; + box-sizing: border-box; + + &:nth-child(1) { + width: 50%; + } + &:nth-child(2) { + width: 35%; + text-align: left; + box-shadow: ${theme.shadows[7]}; + } + &:nth-child(3) { + width: 15%; + box-shadow: ${theme.shadows[7]}; + } + } + } +` + +const MultipleSubscriptionWrapper = styled.div` + > table:not(:nth-last-child(2)) { + margin-bottom: ${theme.spacing(8)}; + } +` diff --git a/src/components/invoices/details/InvoiceDetailsTableBodyLine.tsx b/src/components/invoices/details/InvoiceDetailsTableBodyLine.tsx new file mode 100644 index 000000000..68b064efe --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableBodyLine.tsx @@ -0,0 +1,208 @@ +import { gql } from '@apollo/client' +import { memo } from 'react' + +import { Typography } from '~/components/designSystem' +import { TExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' +import { intlFormatNumber } from '~/core/formats/intlFormatNumber' +import { deserializeAmount } from '~/core/serializers/serializeAmount' +import { + ChargeModelEnum, + CurrencyEnum, + FeeForInvoiceDetailsTableBodyLineGraduatedFragmentDoc, + FeeForInvoiceDetailsTableBodyLineGraduatedPercentageFragmentDoc, + FeeForInvoiceDetailsTableBodyLinePackageFragmentDoc, + FeeForInvoiceDetailsTableBodyLinePercentageFragmentDoc, + FeeForInvoiceDetailsTableBodyLineVolumeFragmentDoc, + FeeTypesEnum, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +import { InvoiceDetailsTableBodyLineGraduated } from './InvoiceDetailsTableBodyLineGraduated' +import { InvoiceDetailsTableBodyLineGraduatedPercentage } from './InvoiceDetailsTableBodyLineGraduatedPercentage' +import { InvoiceDetailsTableBodyLinePackage } from './InvoiceDetailsTableBodyLinePackage' +import { InvoiceDetailsTableBodyLinePercentage } from './InvoiceDetailsTableBodyLinePercentage' +import { InvoiceDetailsTableBodyLineVolume } from './InvoiceDetailsTableBodyLineVolume' + +gql` + fragment FeeForInvoiceDetailsTableBodyLine on Fee { + id + units + preciseUnitAmount + amountCents + eventsCount + charge { + id + chargeModel + minAmountCents + payInAdvance + prorated + } + appliedTaxes { + id + taxRate + } + + ...FeeForInvoiceDetailsTableBodyLineGraduated + ...FeeForInvoiceDetailsTableBodyLineGraduatedPercentage + ...FeeForInvoiceDetailsTableBodyLineVolume + ...FeeForInvoiceDetailsTableBodyLinePackage + ...FeeForInvoiceDetailsTableBodyLinePercentage + } + + ${FeeForInvoiceDetailsTableBodyLineGraduatedFragmentDoc} + ${FeeForInvoiceDetailsTableBodyLineGraduatedPercentageFragmentDoc} + ${FeeForInvoiceDetailsTableBodyLineVolumeFragmentDoc} + ${FeeForInvoiceDetailsTableBodyLinePackageFragmentDoc} + ${FeeForInvoiceDetailsTableBodyLinePercentageFragmentDoc} +` + +type InvoiceDetailsTableBodyLineProps = { + canHaveUnitPrice: boolean + currency: CurrencyEnum + displayName: string + fee: TExtendedRemainingFee | undefined +} + +export const InvoiceDetailsTableBodyLine = memo( + ({ canHaveUnitPrice, currency, displayName, fee }: InvoiceDetailsTableBodyLineProps) => { + const { translate } = useInternationalization() + const chargeModel = fee?.charge?.chargeModel + const isTrueUpFee = fee?.metadata?.isTrueUpFee && !!fee?.charge?.minAmountCents + const subLabel = !canHaveUnitPrice + ? undefined + : fee?.description + ? fee?.description + : chargeModel === ChargeModelEnum.Percentage + ? translate('text_659e67cd63512ef53284303e', { eventsCount: fee?.eventsCount }) + : fee?.charge?.prorated + ? translate('text_659e6b6b8e57e6ff88a34930') + : isTrueUpFee + ? translate('text_659e67cd63512ef53284305a', { + amount: intlFormatNumber( + deserializeAmount(fee?.charge?.minAmountCents, currency), + { + currencyDisplay: 'symbol', + currency, + minimumFractionDigits: 2, + maximumFractionDigits: 15, + }, + ), + }) + : undefined + const isValidGraduatedToHaveDetails = + fee?.charge?.chargeModel === ChargeModelEnum.Graduated && !fee.charge.prorated + const isValidChargeModelToHaveDetails = + isValidGraduatedToHaveDetails || + fee?.charge?.chargeModel === ChargeModelEnum.Volume || + fee?.charge?.chargeModel === ChargeModelEnum.Package || + fee?.charge?.chargeModel === ChargeModelEnum.Percentage || + fee?.charge?.chargeModel === ChargeModelEnum.GraduatedPercentage + const shouldDisplayFeeDetail = + !!fee && + !isTrueUpFee && + !fee?.metadata?.isSubscriptionFee && + !fee.charge?.payInAdvance && + chargeModel !== ChargeModelEnum.Standard && + fee.feeType !== FeeTypesEnum.AddOn && + fee.feeType !== FeeTypesEnum.Credit && + isValidChargeModelToHaveDetails && + canHaveUnitPrice + + return ( + <> + + + + {displayName} + {isTrueUpFee ? ` - ${translate('text_64463aaa34904c00a23be4f7')}` : ''} + + {!!subLabel && ( + + {subLabel} + + )} + + {/* Basic line infos */} + {!shouldDisplayFeeDetail && ( + <> + + + {fee?.units || 1} + + + {canHaveUnitPrice && ( + + + {intlFormatNumber(fee?.preciseUnitAmount || 0, { + currencyDisplay: 'symbol', + currency, + maximumFractionDigits: 15, + })} + + + )} + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(deserializeAmount(fee?.amountCents || 0, currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + + {shouldDisplayFeeDetail && ( + <> + {chargeModel === ChargeModelEnum.Graduated ? ( + + ) : chargeModel === ChargeModelEnum.GraduatedPercentage ? ( + + ) : chargeModel === ChargeModelEnum.Volume ? ( + + ) : chargeModel === ChargeModelEnum.Package ? ( + + ) : chargeModel === ChargeModelEnum.Percentage ? ( + + ) : null} + + + + {translate('text_659e67cd63512ef532843154')} + + + + + {intlFormatNumber(deserializeAmount(fee?.amountCents || 0, currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + + )} + + ) + }, +) + +InvoiceDetailsTableBodyLine.displayName = 'InvoiceDetailsTableBodyLine' diff --git a/src/components/invoices/details/InvoiceDetailsTableBodyLineGraduated.tsx b/src/components/invoices/details/InvoiceDetailsTableBodyLineGraduated.tsx new file mode 100644 index 000000000..a40721770 --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableBodyLineGraduated.tsx @@ -0,0 +1,172 @@ +import { gql } from '@apollo/client' +import { memo } from 'react' + +import { Typography } from '~/components/designSystem' +import { TExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' +import { intlFormatNumber } from '~/core/formats/intlFormatNumber' +import { CurrencyEnum } from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +gql` + fragment FeeForInvoiceDetailsTableBodyLineGraduated on Fee { + id + appliedTaxes { + id + taxRate + } + amountDetails { + graduatedRanges { + flatUnitAmount + fromValue + perUnitAmount + perUnitTotalAmount + toValue + totalWithFlatAmount + units + } + } + } +` + +type InvoiceDetailsTableBodyLineGraduatedProps = { + currency: CurrencyEnum + fee: TExtendedRemainingFee | undefined +} + +export const InvoiceDetailsTableBodyLineGraduated = memo( + ({ currency, fee }: InvoiceDetailsTableBodyLineGraduatedProps) => { + const { translate } = useInternationalization() + + return ( + <> + {fee?.amountDetails?.graduatedRanges?.map((graduatedRange, i) => ( + + + + {i === 0 + ? translate('text_659e67cd63512ef532843070', { + toValue: Number(graduatedRange?.toValue), + }) + : i === (fee?.amountDetails?.graduatedRanges?.length || 0) - 1 + ? translate('text_659e67cd63512ef5328430e6', { + fromValue: Number(graduatedRange?.fromValue), + }) + : translate('text_659e67cd63512ef5328430af', { + fromValue: Number(graduatedRange?.fromValue), + toValue: Number(graduatedRange?.toValue), + })} + + + + + {Number(graduatedRange.units)} + + + + + {intlFormatNumber(Number(graduatedRange?.perUnitAmount) || 0, { + currencyDisplay: 'symbol', + currency, + maximumFractionDigits: 15, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(graduatedRange.perUnitTotalAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + ))} + + {!!fee?.amountDetails?.graduatedRanges?.length && + fee?.amountDetails?.graduatedRanges?.map((graduatedRange, i) => { + if (Number(graduatedRange?.flatUnitAmount) === 0) return null + + return ( + + + + {i === 0 + ? translate('text_659e67cd63512ef53284310e', { + toValue: Number(graduatedRange?.toValue), + }) + : i === (fee?.amountDetails?.graduatedRanges?.length || 0) - 1 + ? translate('text_659e67cd63512ef53284314a', { + fromValue: Number(graduatedRange?.fromValue), + }) + : translate('text_659e67cd63512ef532843136', { + fromValue: Number(graduatedRange?.fromValue), + toValue: Number(graduatedRange?.toValue), + })} + + + + + 1 + + + + + {intlFormatNumber(Number(graduatedRange?.flatUnitAmount) || 0, { + currencyDisplay: 'symbol', + currency, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(graduatedRange.flatUnitAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + ) + })} + + ) + }, +) + +InvoiceDetailsTableBodyLineGraduated.displayName = 'InvoiceDetailsTableBodyLineGraduated' diff --git a/src/components/invoices/details/InvoiceDetailsTableBodyLineGraduatedPercentage.tsx b/src/components/invoices/details/InvoiceDetailsTableBodyLineGraduatedPercentage.tsx new file mode 100644 index 000000000..b256bba5f --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableBodyLineGraduatedPercentage.tsx @@ -0,0 +1,178 @@ +import { gql } from '@apollo/client' +import { memo } from 'react' + +import { Typography } from '~/components/designSystem' +import { TExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' +import { intlFormatNumber } from '~/core/formats/intlFormatNumber' +import { CurrencyEnum } from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +gql` + fragment FeeForInvoiceDetailsTableBodyLineGraduatedPercentage on Fee { + id + appliedTaxes { + id + taxRate + } + amountDetails { + graduatedPercentageRanges { + flatUnitAmount + fromValue + perUnitTotalAmount + rate + toValue + totalWithFlatAmount + units + } + } + } +` + +type InvoiceDetailsTableBodyLineGraduatedPercentageProps = { + currency: CurrencyEnum + fee: TExtendedRemainingFee | undefined +} + +export const InvoiceDetailsTableBodyLineGraduatedPercentage = memo( + ({ currency, fee }: InvoiceDetailsTableBodyLineGraduatedPercentageProps) => { + const { translate } = useInternationalization() + + return ( + <> + {fee?.amountDetails?.graduatedPercentageRanges?.map((graduatedPercentageRange, i) => ( + + + + {i === 0 + ? translate('text_659e67cd63512ef532843070', { + toValue: Number(graduatedPercentageRange?.toValue), + }) + : i === (fee?.amountDetails?.graduatedPercentageRanges?.length || 0) - 1 + ? translate('text_659e67cd63512ef5328430e6', { + fromValue: Number(graduatedPercentageRange?.fromValue), + }) + : translate('text_659e67cd63512ef5328430af', { + fromValue: Number(graduatedPercentageRange?.fromValue), + toValue: Number(graduatedPercentageRange?.toValue), + })} + + + + + {Number(graduatedPercentageRange.units)} + + + + + {intlFormatNumber(Number(graduatedPercentageRange?.rate || 0) / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(graduatedPercentageRange.perUnitTotalAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + ))} + + {!!fee?.amountDetails?.graduatedPercentageRanges?.length && + fee?.amountDetails?.graduatedPercentageRanges?.map((graduatedPercentageRange, i) => { + if (Number(graduatedPercentageRange?.flatUnitAmount) === 0) return null + + return ( + + + + {i === 0 + ? translate('text_659e67cd63512ef53284310e', { + toValue: Number(graduatedPercentageRange?.toValue), + }) + : i === (fee?.amountDetails?.graduatedPercentageRanges?.length || 0) - 1 + ? translate('text_659e67cd63512ef53284314a', { + fromValue: Number(graduatedPercentageRange?.fromValue), + }) + : translate('text_659e67cd63512ef532843136', { + fromValue: Number(graduatedPercentageRange?.fromValue), + toValue: Number(graduatedPercentageRange?.toValue), + })} + + + + + 1 + + + + + {intlFormatNumber(Number(graduatedPercentageRange?.flatUnitAmount) || 0, { + currencyDisplay: 'symbol', + currency, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(graduatedPercentageRange.flatUnitAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + ) + })} + + ) + }, +) + +InvoiceDetailsTableBodyLineGraduatedPercentage.displayName = + 'InvoiceDetailsTableBodyLineGraduatedPercentage' diff --git a/src/components/invoices/details/InvoiceDetailsTableBodyLinePackage.tsx b/src/components/invoices/details/InvoiceDetailsTableBodyLinePackage.tsx new file mode 100644 index 000000000..63fffe6ae --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableBodyLinePackage.tsx @@ -0,0 +1,149 @@ +import { gql } from '@apollo/client' +import { memo } from 'react' + +import { Typography } from '~/components/designSystem' +import { TExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' +import { intlFormatNumber } from '~/core/formats/intlFormatNumber' +import { deserializeAmount } from '~/core/serializers/serializeAmount' +import { CurrencyEnum } from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +gql` + fragment FeeForInvoiceDetailsTableBodyLinePackage on Fee { + id + units + amountCents + appliedTaxes { + id + taxRate + } + amountDetails { + freeUnits + paidUnits + perPackageSize + perPackageUnitAmount + } + } +` + +type InvoiceDetailsTableBodyLinePackageProps = { + currency: CurrencyEnum + fee: TExtendedRemainingFee | undefined +} + +export const InvoiceDetailsTableBodyLinePackage = memo( + ({ currency, fee }: InvoiceDetailsTableBodyLinePackageProps) => { + const { translate } = useInternationalization() + const amountDetails = fee?.amountDetails + + return ( + <> + {Number(amountDetails?.freeUnits || 0) > 0 && ( + + + + {translate('text_659e67cd63512ef53284303c', { + freeUnits: Number(amountDetails?.freeUnits || 1), + })} + + + + + {Number(amountDetails?.freeUnits || 1)} + + + + + {intlFormatNumber(0, { + currencyDisplay: 'symbol', + currency, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(0, { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + + + + + {translate('text_659e67cd63512ef532843064')} + + + + + {Number(amountDetails?.paidUnits || 1)} + + + + + {translate('text_659e67cd63512ef532843074', { + perPackageUnitAmount: intlFormatNumber( + Number(amountDetails?.perPackageUnitAmount) || 0, + { + currencyDisplay: 'symbol', + currency, + }, + ), + perPackageSize: Number(amountDetails?.perPackageSize || 1), + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(deserializeAmount(Number(fee?.amountCents || 0), currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + + ) + }, +) + +InvoiceDetailsTableBodyLinePackage.displayName = 'InvoiceDetailsTableBodyLinePackage' diff --git a/src/components/invoices/details/InvoiceDetailsTableBodyLinePercentage.tsx b/src/components/invoices/details/InvoiceDetailsTableBodyLinePercentage.tsx new file mode 100644 index 000000000..991a5ff63 --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableBodyLinePercentage.tsx @@ -0,0 +1,261 @@ +import { gql } from '@apollo/client' +import { memo } from 'react' + +import { Typography } from '~/components/designSystem' +import { TExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' +import { intlFormatNumber } from '~/core/formats/intlFormatNumber' +import { deserializeAmount } from '~/core/serializers/serializeAmount' +import { CurrencyEnum } from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +gql` + fragment FeeForInvoiceDetailsTableBodyLinePercentage on Fee { + id + units + amountCents + appliedTaxes { + id + taxRate + } + amountDetails { + fixedFeeTotalAmount + fixedFeeUnitAmount + freeEvents + freeUnits + minMaxAdjustmentTotalAmount + paidEvents + paidUnits + perUnitTotalAmount + rate + units + } + } +` + +type InvoiceDetailsTableBodyLinePercentageProps = { + currency: CurrencyEnum + fee: TExtendedRemainingFee | undefined +} + +export const InvoiceDetailsTableBodyLinePercentage = memo( + ({ currency, fee }: InvoiceDetailsTableBodyLinePercentageProps) => { + const { translate } = useInternationalization() + const { + freeEvents, + freeUnits, + paidUnits, + rate, + perUnitTotalAmount, + fixedFeeUnitAmount, + paidEvents, + minMaxAdjustmentTotalAmount, + } = fee?.amountDetails || {} + + return ( + <> + {Number(freeUnits || 0) > 0 && ( + + + + {translate( + 'text_659e67cd63512ef532843046', + { + freeEvents: Number(freeEvents || 0), + }, + Number(freeEvents || 0), + )} + + + + + {Number(freeUnits || 1)} + + + + + {intlFormatNumber(0, { + currencyDisplay: 'symbol', + currency, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(0, { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + + + + + {translate('text_659e67cd63512ef53284306e')} + + + + + {Number(paidUnits || 1)} + + + + + {intlFormatNumber(Number(rate || 0) / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(deserializeAmount(Number(perUnitTotalAmount || 0), currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + + {Number(fixedFeeUnitAmount || 0) > 0 && ( + + + + {translate('text_659e67cd63512ef53284308f')} + {freeEvents} + + + + + {paidEvents || 1} + + + + + {intlFormatNumber(Number(fixedFeeUnitAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(fixedFeeUnitAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + + {Number(minMaxAdjustmentTotalAmount || 0) !== 0 && ( + + + + {translate('text_659e67cd63512ef5328430ad')} + + + + + 1 + + + + + {intlFormatNumber(Number(minMaxAdjustmentTotalAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(minMaxAdjustmentTotalAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + + ) + }, +) + +InvoiceDetailsTableBodyLinePercentage.displayName = 'InvoiceDetailsTableBodyLinePercentage' diff --git a/src/components/invoices/details/InvoiceDetailsTableBodyLineVolume.tsx b/src/components/invoices/details/InvoiceDetailsTableBodyLineVolume.tsx new file mode 100644 index 000000000..ceb403852 --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableBodyLineVolume.tsx @@ -0,0 +1,141 @@ +import { gql } from '@apollo/client' +import { memo } from 'react' + +import { Typography } from '~/components/designSystem' +import { TExtendedRemainingFee } from '~/core/formats/formatInvoiceItemsMap' +import { intlFormatNumber } from '~/core/formats/intlFormatNumber' +import { CurrencyEnum } from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +gql` + fragment FeeForInvoiceDetailsTableBodyLineVolume on Fee { + id + units + appliedTaxes { + id + taxRate + } + amountDetails { + flatUnitAmount + perUnitAmount + perUnitTotalAmount + } + } +` + +type InvoiceDetailsTableBodyLineVolumeProps = { + currency: CurrencyEnum + fee: TExtendedRemainingFee | undefined +} + +export const InvoiceDetailsTableBodyLineVolume = memo( + ({ currency, fee }: InvoiceDetailsTableBodyLineVolumeProps) => { + const { translate } = useInternationalization() + const amountDetails = fee?.amountDetails + + return ( + <> + + + + {translate('text_659e67cd63512ef532843078')} + + + + + {Number(fee?.units || 1)} + + + + + {intlFormatNumber(Number(amountDetails?.perUnitAmount) || 0, { + currencyDisplay: 'symbol', + currency, + maximumFractionDigits: 15, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(amountDetails?.perUnitTotalAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + + {Number(amountDetails?.flatUnitAmount || 0) > 0 && ( + <> + + + + {translate('text_659e67cd63512ef5328430b5')} + + + + + 1 + + + + + {intlFormatNumber(Number(amountDetails?.flatUnitAmount) || 0, { + currencyDisplay: 'symbol', + currency, + })} + + + + + {fee?.appliedTaxes?.length + ? fee?.appliedTaxes.map((appliedTaxes) => ( + + {intlFormatNumber(appliedTaxes.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + })} + + )) + : '0%'} + + + + + {intlFormatNumber(Number(amountDetails?.flatUnitAmount || 0), { + currencyDisplay: 'symbol', + currency, + })} + + + + + )} + + ) + }, +) + +InvoiceDetailsTableBodyLineVolume.displayName = 'InvoiceDetailsTableBodyLineVolume' diff --git a/src/components/invoices/details/InvoiceDetailsTableFooter.tsx b/src/components/invoices/details/InvoiceDetailsTableFooter.tsx new file mode 100644 index 000000000..cfe5c24c9 --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableFooter.tsx @@ -0,0 +1,284 @@ +import { gql } from '@apollo/client' +import { memo } from 'react' +import styled from 'styled-components' + +import { Alert, Typography } from '~/components/designSystem' +import { intlFormatNumber } from '~/core/formats/intlFormatNumber' +import { deserializeAmount } from '~/core/serializers/serializeAmount' +import { + CurrencyEnum, + InvoiceForDetailsTableFooterFragment, + InvoiceStatusTypeEnum, + InvoiceTypeEnum, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +gql` + fragment InvoiceForDetailsTableFooter on Invoice { + couponsAmountCents + creditNotesAmountCents + subTotalExcludingTaxesAmountCents + subTotalIncludingTaxesAmountCents + totalAmountCents + currency + invoiceType + status + prepaidCreditAmountCents + versionNumber + appliedTaxes { + id + amountCents + feesAmountCents + taxRate + taxName + } + } +` + +interface InvoiceDetailsTableFooterProps { + invoice: InvoiceForDetailsTableFooterFragment +} + +export const InvoiceDetailsTableFooter = memo(({ invoice }: InvoiceDetailsTableFooterProps) => { + const { translate } = useInternationalization() + const currency = invoice?.currency || CurrencyEnum.Usd + const isLegacyInvoice = invoice?.versionNumber < 3 + + return ( + + {invoice.invoiceType !== InvoiceTypeEnum.Credit && ( + <> + {invoice.status !== InvoiceStatusTypeEnum.Draft && + !!Number(invoice?.couponsAmountCents) && + !isLegacyInvoice && ( + + + + + {translate('text_637ccf8133d2c9a7d11ce705')} + + + + + - + {intlFormatNumber( + deserializeAmount(invoice?.couponsAmountCents || 0, currency), + { + currencyDisplay: 'symbol', + currency, + }, + )} + + + + )} + + + + + {translate('text_637ccf8133d2c9a7d11ce6f9')} + + + + + {intlFormatNumber( + deserializeAmount(invoice?.subTotalExcludingTaxesAmountCents || 0, currency), + { + currencyDisplay: 'symbol', + currency, + }, + )} + + + + {!!invoice.appliedTaxes?.length ? ( + <> + {invoice.appliedTaxes.map((appliedTax, i) => ( + + + + + {translate('text_64c013a424ce2f00dffb7f4d', { + name: appliedTax.taxName, + rate: intlFormatNumber(appliedTax.taxRate / 100 || 0, { + maximumFractionDigits: 2, + style: 'percent', + }), + amount: intlFormatNumber( + deserializeAmount(appliedTax.feesAmountCents || 0, currency), + { + currencyDisplay: 'symbol', + currency, + }, + ), + })} + + + + + {intlFormatNumber(deserializeAmount(appliedTax.amountCents || 0, currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + ))} + + ) : ( + + + + + {`${translate('text_637ccf8133d2c9a7d11ce6fd')} (0%)`} + + + + + {intlFormatNumber(0, { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + + + + + {translate('text_637ccf8133d2c9a7d11ce701')} + + + + + {intlFormatNumber( + deserializeAmount(invoice?.subTotalIncludingTaxesAmountCents || 0, currency), + { + currencyDisplay: 'symbol', + currency, + }, + )} + + + + + )} + {!!Number(invoice?.creditNotesAmountCents) && ( + + + + + {translate('text_637ccf8133d2c9a7d11ce708')} + + + + + - + {intlFormatNumber(deserializeAmount(invoice?.creditNotesAmountCents || 0, currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + {invoice.status !== InvoiceStatusTypeEnum.Draft && + !!Number(invoice?.couponsAmountCents) && + !!isLegacyInvoice && ( + + + + + {translate('text_637ccf8133d2c9a7d11ce705')} + + + + + - + {intlFormatNumber(deserializeAmount(invoice?.couponsAmountCents || 0, currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + )} + {invoice.status !== InvoiceStatusTypeEnum.Draft && + !!Number(invoice?.prepaidCreditAmountCents) && ( + + + + + {translate('text_6391f05df4bf96d81f3660a7')} + + + + + - + {intlFormatNumber( + deserializeAmount(invoice?.prepaidCreditAmountCents || 0, currency), + { + currencyDisplay: 'symbol', + currency, + }, + )} + + + + )} + + + + + {invoice.invoiceType === InvoiceTypeEnum.Credit + ? translate('text_63887b52e514213fed57fc1c') + : translate('text_637ccf8133d2c9a7d11ce70d')} + + + + + {intlFormatNumber(deserializeAmount(invoice?.totalAmountCents || 0, currency), { + currencyDisplay: 'symbol', + currency, + })} + + + + {invoice.status === InvoiceStatusTypeEnum.Draft && ( + + + + {translate('text_63b6f4e9b074e3b8beebb97f')} + + + )} + + ) +}) + +const NoShadowTD = styled.td` + box-shadow: none !important; +` + +InvoiceDetailsTableFooter.displayName = 'InvoiceDetailsTableFooter' diff --git a/src/components/invoices/details/InvoiceDetailsTableHeader.tsx b/src/components/invoices/details/InvoiceDetailsTableHeader.tsx new file mode 100644 index 000000000..ef176cf2e --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTableHeader.tsx @@ -0,0 +1,51 @@ +import { memo } from 'react' + +import { Typography } from '~/components/designSystem' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +type InvoiceDetailsTableHeaderProps = { + canHaveUnitPrice: boolean + displayName: string +} + +export const InvoiceDetailsTableHeader = memo( + ({ canHaveUnitPrice, displayName }: InvoiceDetailsTableHeaderProps) => { + const { translate } = useInternationalization() + + return ( + + + + + {displayName} + + + + + {translate('text_65771fa3f4ab9a00720726ce')} + + + {canHaveUnitPrice && ( + + + {translate('text_6453819268763979024ad089')} + + + )} + + + {translate('text_636bedf292786b19d3398f06')} + + + + + {translate('text_634d631acf4dce7b0127a3a6')} + + + + + ) + }, +) + +InvoiceDetailsTableHeader.displayName = 'InvoiceDetailsTableHeader' diff --git a/src/components/invoices/details/InvoiceDetailsTablePeriodLine.tsx b/src/components/invoices/details/InvoiceDetailsTablePeriodLine.tsx new file mode 100644 index 000000000..6847af01e --- /dev/null +++ b/src/components/invoices/details/InvoiceDetailsTablePeriodLine.tsx @@ -0,0 +1,21 @@ +import { Typography } from '~/components/designSystem' + +type InvoiceDetailsTablePeriodLineProps = { + canHaveUnitPrice: boolean + period: string +} + +export const InvoiceDetailsTablePeriodLine = ({ + canHaveUnitPrice, + period, +}: InvoiceDetailsTablePeriodLineProps) => { + return ( + + + + {period} + + + + ) +} diff --git a/src/components/settings/integrations/AddAdyenDialog.tsx b/src/components/settings/integrations/AddAdyenDialog.tsx index 3a7690331..2a489d37e 100644 --- a/src/components/settings/integrations/AddAdyenDialog.tsx +++ b/src/components/settings/integrations/AddAdyenDialog.tsx @@ -1,148 +1,298 @@ import { gql } from '@apollo/client' +import { Stack } from '@mui/material' import { useFormik } from 'formik' -import { forwardRef } from 'react' +import { forwardRef, RefObject, useImperativeHandle, useRef, useState } from 'react' import { useNavigate } from 'react-router' +import { generatePath } from 'react-router-dom' import styled from 'styled-components' import { object, string } from 'yup' import { Button, Dialog, DialogRef } from '~/components/designSystem' import { TextInputField } from '~/components/form' import { addToast } from '~/core/apolloClient' -import { ADYEN_INTEGRATION_ROUTE } from '~/core/router' +import { ADYEN_INTEGRATION_DETAILS_ROUTE } from '~/core/router' import { AddAdyenPaymentProviderInput, - AdyenIntegrationFragmentDoc, + AddAdyenProviderDialogFragment, + AdyenIntegrationDetailsFragmentDoc, + LagoApiError, useAddAdyenApiKeyMutation, + useGetProviderByCodeForAdyenLazyQuery, + useUpdateAdyenApiKeyMutation, } from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' import { theme } from '~/styles' +import { DeleteAdyenIntegrationDialogRef } from './DeleteAdyenIntegrationDialog' + gql` + fragment AddAdyenProviderDialog on AdyenProvider { + id + name + code + apiKey + hmacKey + livePrefix + merchantAccount + } + + query getProviderByCodeForAdyen($code: String) { + paymentProvider(code: $code) { + ... on AdyenProvider { + id + } + ... on GocardlessProvider { + id + } + ... on StripeProvider { + id + } + } + } + mutation addAdyenApiKey($input: AddAdyenPaymentProviderInput!) { addAdyenPaymentProvider(input: $input) { id - apiKey - hmacKey - livePrefix - merchantAccount - ...AdyenIntegration + ...AddAdyenProviderDialog + ...AdyenIntegrationDetails + } + } + + mutation updateAdyenApiKey($input: UpdateAdyenPaymentProviderInput!) { + updateAdyenPaymentProvider(input: $input) { + id + + ...AddAdyenProviderDialog + ...AdyenIntegrationDetails } } - ${AdyenIntegrationFragmentDoc} + ${AdyenIntegrationDetailsFragmentDoc} ` -export interface AddAdyenDialogRef extends DialogRef {} +type TAddAdyenDialogProps = Partial<{ + deleteModalRef: RefObject + provider: AddAdyenProviderDialogFragment + deleteDialogCallback: Function +}> -interface AddStripDialog { - isEdition?: boolean +export interface AddAdyenDialogRef { + openDialog: (props?: TAddAdyenDialogProps) => unknown + closeDialog: () => unknown } -export const AddAdyenDialog = forwardRef( - ({ isEdition }: AddStripDialog, ref) => { - const { translate } = useInternationalization() - const navigate = useNavigate() - const formikProps = useFormik({ - initialValues: { - apiKey: '', - hmacKey: undefined, - livePrefix: undefined, - merchantAccount: '', - }, - validationSchema: object().shape({ - apiKey: string().required(''), - hmacKey: string(), - livePrefix: string(), - merchantAccount: string().required(''), - }), - onSubmit: async (values) => { +export const AddAdyenDialog = forwardRef((_, ref) => { + const { translate } = useInternationalization() + const navigate = useNavigate() + const dialogRef = useRef(null) + const [localData, setLocalData] = useState(undefined) + const adyenProvider = localData?.provider + const isEdition = !!adyenProvider + + const [addApiKey] = useAddAdyenApiKeyMutation({ + onCompleted({ addAdyenPaymentProvider }) { + if (addAdyenPaymentProvider?.id) { + navigate( + generatePath(ADYEN_INTEGRATION_DETAILS_ROUTE, { + integrationId: addAdyenPaymentProvider.id, + }), + ) + + addToast({ + message: translate('text_645d071272418a14c1c76a93'), + severity: 'success', + }) + } + }, + }) + + const [updateApiKey] = useUpdateAdyenApiKeyMutation({ + onCompleted({ updateAdyenPaymentProvider }) { + if (updateAdyenPaymentProvider?.id) { + addToast({ + message: translate('text_645d071272418a14c1c76a3e'), + severity: 'success', + }) + } + }, + }) + + const [getAdyenProviderByCode] = useGetProviderByCodeForAdyenLazyQuery() + + const formikProps = useFormik({ + initialValues: { + name: adyenProvider?.name || '', + code: adyenProvider?.code || '', + apiKey: adyenProvider?.apiKey || '', + hmacKey: adyenProvider?.hmacKey || undefined, + livePrefix: adyenProvider?.livePrefix || undefined, + merchantAccount: adyenProvider?.merchantAccount || '', + }, + validationSchema: object().shape({ + name: string(), + code: string().required(''), + apiKey: string().required(''), + hmacKey: string(), + livePrefix: string(), + merchantAccount: string().required(''), + }), + onSubmit: async ({ apiKey, merchantAccount, hmacKey, livePrefix, ...values }, formikBag) => { + const res = await getAdyenProviderByCode({ + context: { silentErrorCodes: [LagoApiError.NotFound] }, + variables: { + code: values.code, + }, + }) + const isNotAllowedToMutate = + (!!res.data?.paymentProvider?.id && !isEdition) || + (isEdition && + !!res.data?.paymentProvider?.id && + res.data?.paymentProvider?.id !== adyenProvider?.id) + + if (isNotAllowedToMutate) { + formikBag.setFieldError('code', translate('text_632a2d437e341dcc76817556')) + return + } + + if (isEdition) { + await updateApiKey({ + variables: { + input: { + ...values, + id: adyenProvider?.id || '', + }, + }, + }) + } else { await addApiKey({ variables: { - input: values, + input: { ...values, apiKey, merchantAccount, hmacKey, livePrefix }, }, - refetchQueries: ['AdyenIntegrationsSetting'], }) - }, - validateOnMount: true, - enableReinitialize: true, - }) - const [addApiKey] = useAddAdyenApiKeyMutation({ - onCompleted({ addAdyenPaymentProvider }) { - if (addAdyenPaymentProvider?.id) { - navigate(ADYEN_INTEGRATION_ROUTE) - addToast({ - message: translate( - isEdition ? 'text_645d071272418a14c1c76a3e' : 'text_645d071272418a14c1c76a93', - ), - severity: 'success', - }) - } - }, - }) - - return ( - { - formikProps.resetForm() - }} - actions={({ closeDialog }) => ( - <> + } + + dialogRef.current?.closeDialog() + }, + validateOnMount: true, + enableReinitialize: true, + }) + + useImperativeHandle(ref, () => ({ + openDialog: (data) => { + setLocalData(data) + dialogRef.current?.openDialog() + }, + closeDialog: () => dialogRef.current?.closeDialog(), + })) + + return ( + ( + + {isEdition && ( + + )} + - - )} - > - + + + )} + > + + + + + + + {(!isEdition || !!adyenProvider.livePrefix) && ( + )} + {(!isEdition || !!adyenProvider.hmacKey) && ( - - - ) - }, -) + )} + + + ) +}) const Content = styled.div` margin-bottom: ${theme.spacing(8)}; @@ -152,4 +302,15 @@ const Content = styled.div` } ` +const InlineInputs = styled.div` + display: flex; + flex-direction: row; + align-items: flex-start; + gap: ${theme.spacing(6)}; + + > * { + flex: 1; + } +` + AddAdyenDialog.displayName = 'AddAdyenDialog' diff --git a/src/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog.tsx b/src/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog.tsx index 46bfad4b2..2069004d7 100644 --- a/src/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog.tsx +++ b/src/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog.tsx @@ -33,7 +33,7 @@ gql` successRedirectUrl } - fragment stripeForCreateAndEditSuccessRedirectUrl on StripeProvider { + fragment StripeForCreateAndEditSuccessRedirectUrl on StripeProvider { id successRedirectUrl } @@ -138,6 +138,7 @@ export const AddEditDeleteSuccessRedirectUrlDialog = | UpdateStripePaymentProviderInput >({ initialValues: { + id: localData?.provider?.id || '', successRedirectUrl: localData?.provider?.successRedirectUrl || '', }, validateOnMount: true, @@ -153,15 +154,11 @@ export const AddEditDeleteSuccessRedirectUrlDialog = } const method = methodLoojup[localData?.type as LocalProviderType['type']] - // localData?.type === AddEditDeleteSuccessRedirectUrlDialogProviderType.Adyen - // ? updateAdyenProvider - // : localData?.type === AddEditDeleteSuccessRedirectUrlDialogProviderType.Stripe - // ? updateStripeProvider - // : updateGocardlessProvider const res = await method({ variables: { input: { + id: values.id, successRedirectUrl: localData?.mode === AddEditDeleteSuccessRedirectUrlDialogMode.Delete ? null diff --git a/src/components/settings/integrations/AddGocardlessDialog.tsx b/src/components/settings/integrations/AddGocardlessDialog.tsx new file mode 100644 index 000000000..a7c52aee6 --- /dev/null +++ b/src/components/settings/integrations/AddGocardlessDialog.tsx @@ -0,0 +1,251 @@ +import { gql } from '@apollo/client' +import { Stack } from '@mui/material' +import { useFormik } from 'formik' +import { forwardRef, RefObject, useImperativeHandle, useRef, useState } from 'react' +import { useNavigate } from 'react-router' +import { generatePath } from 'react-router-dom' +import styled from 'styled-components' +import { object, string } from 'yup' + +import { Button, Dialog, DialogRef } from '~/components/designSystem' +import { TextInputField } from '~/components/form' +import { addToast, envGlobalVar } from '~/core/apolloClient' +import { GOCARDLESS_INTEGRATION_DETAILS_ROUTE } from '~/core/router' +import { + AddGocardlessPaymentProviderInput, + AddGocardlessProviderDialogFragment, + GocardlessIntegrationDetailsFragmentDoc, + LagoApiError, + useGetProviderByCodeForGocardlessLazyQuery, + useUpdateGocardlessApiKeyMutation, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' +import { theme } from '~/styles' + +import { DeleteGocardlessIntegrationDialogRef } from './DeleteGocardlessIntegrationDialog' + +gql` + fragment AddGocardlessProviderDialog on GocardlessProvider { + id + name + code + } + + query getProviderByCodeForGocardless($code: String) { + paymentProvider(code: $code) { + ... on GocardlessProvider { + id + } + ... on AdyenProvider { + id + } + ... on StripeProvider { + id + } + } + } + + mutation updateGocardlessApiKey($input: UpdateGocardlessPaymentProviderInput!) { + updateGocardlessPaymentProvider(input: $input) { + id + ...AddGocardlessProviderDialog + ...GocardlessIntegrationDetails + } + } + + ${GocardlessIntegrationDetailsFragmentDoc} +` + +type TAddGocardlessDialogProps = Partial<{ + deleteModalRef: RefObject + provider: AddGocardlessProviderDialogFragment + deleteDialogCallback: Function +}> + +export interface AddGocardlessDialogRef { + openDialog: (props?: TAddGocardlessDialogProps) => unknown + closeDialog: () => unknown +} + +export const AddGocardlessDialog = forwardRef((_, ref) => { + const navigate = useNavigate() + const dialogRef = useRef(null) + const { lagoOauthProxyUrl } = envGlobalVar() + + const { translate } = useInternationalization() + const [localData, setLocalData] = useState(undefined) + const gocardlessProvider = localData?.provider + const isEdition = !!gocardlessProvider + + const [updateApiKey] = useUpdateGocardlessApiKeyMutation({ + onCompleted({ updateGocardlessPaymentProvider }) { + if (updateGocardlessPaymentProvider?.id) { + navigate( + generatePath(GOCARDLESS_INTEGRATION_DETAILS_ROUTE, { + integrationId: updateGocardlessPaymentProvider.id, + }), + ) + + addToast({ + message: translate( + isEdition ? 'Edit gocardless success toast' : 'Add gocardless success toast', + ), + severity: 'success', + }) + } + }, + }) + + const [getGocardlessProviderByCode] = useGetProviderByCodeForGocardlessLazyQuery() + + const formikProps = useFormik({ + initialValues: { + code: gocardlessProvider?.code || '', + name: gocardlessProvider?.name || '', + }, + validationSchema: object().shape({ + name: string(), + code: string().required(''), + }), + onSubmit: async (values, formikBag) => { + const res = await getGocardlessProviderByCode({ + context: { silentErrorCodes: [LagoApiError.NotFound] }, + variables: { + code: values.code, + }, + }) + const isNotAllowedToMutate = + (!!res.data?.paymentProvider?.id && !isEdition) || + (isEdition && + !!res.data?.paymentProvider?.id && + res.data?.paymentProvider?.id !== gocardlessProvider?.id) + + if (isNotAllowedToMutate) { + formikBag.setFieldError('code', translate('text_632a2d437e341dcc76817556')) + return + } + + if (isEdition) { + await updateApiKey({ + variables: { + input: { ...values, id: gocardlessProvider?.id || '' }, + }, + }) + + dialogRef.current?.closeDialog() + } else { + window.open( + `${lagoOauthProxyUrl}/gocardless/auth?lago_name=${values.name}&lago_code=${values.code}`, + ) + dialogRef.current?.closeDialog() + } + }, + validateOnMount: true, + enableReinitialize: true, + }) + + useImperativeHandle(ref, () => ({ + openDialog: (data) => { + setLocalData(data) + dialogRef.current?.openDialog() + }, + closeDialog: () => dialogRef.current?.closeDialog(), + })) + + return ( + { + formikProps.resetForm() + }} + actions={({ closeDialog }) => ( + + {isEdition && ( + + )} + + + + + + )} + > + + + + + + + + ) +}) + +const Content = styled.div` + margin-bottom: ${theme.spacing(8)}; + + > *:not(:last-child) { + margin-bottom: ${theme.spacing(6)}; + } +` + +const InlineInputs = styled.div` + display: flex; + flex-direction: row; + align-items: flex-start; + gap: ${theme.spacing(6)}; + + > * { + flex: 1; + } +` + +AddGocardlessDialog.displayName = 'AddGocardlessDialog' diff --git a/src/components/settings/integrations/AddLagoTaxManagementDialog.tsx b/src/components/settings/integrations/AddLagoTaxManagementDialog.tsx index 67aa04cb0..05b908b48 100644 --- a/src/components/settings/integrations/AddLagoTaxManagementDialog.tsx +++ b/src/components/settings/integrations/AddLagoTaxManagementDialog.tsx @@ -1,4 +1,3 @@ -// TODO: import { gql } from '@apollo/client' import { useFormik } from 'formik' import { forwardRef } from 'react' @@ -15,13 +14,13 @@ import { TAX_MANAGEMENT_INTEGRATION_ROUTE } from '~/core/router' import { CountryCode, UpdateOrganizationInput, - useUpdateOrgaForTagoTaxManagementMutation, + useUpdateOrgaForLagoTaxManagementMutation, } from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' import { theme } from '~/styles' gql` - mutation updateOrgaForTagoTaxManagement($input: UpdateOrganizationInput!) { + mutation updateOrgaForLagoTaxManagement($input: UpdateOrganizationInput!) { updateOrganization(input: $input) { id } @@ -58,7 +57,7 @@ export const AddLagoTaxManagementDialog = forwardRef + provider: AddStripeProviderDialogFragment + deleteDialogCallback: Function +}> -interface AddStripDialog { - isEdition?: boolean +export interface AddStripeDialogRef { + openDialog: (props?: TAddStripeDialogProps) => unknown + closeDialog: () => unknown } -export const AddStripeDialog = forwardRef( - ({ isEdition }: AddStripDialog, ref) => { - const { translate } = useInternationalization() - const [stripeApiKey, setStripeApiKey] = useState('') - const navigate = useNavigate() - const [addApiKey] = useAddStripeApiKeyMutation({ - onCompleted({ addStripePaymentProvider }) { - if (addStripePaymentProvider?.id) { - if (!isEdition) { - navigate(STRIPE_INTEGRATION_ROUTE) - } - setStripeApiKey('') - addToast({ - message: translate( - isEdition ? 'text_62b1edddbf5f461ab97126f6' : 'text_62b1edddbf5f461ab9712743', - ), - severity: 'success', - }) - } - }, - }) - - return ( - { - setStripeApiKey('') - }} - actions={({ closeDialog }) => ( - <> +export const AddStripeDialog = forwardRef((_, ref) => { + const navigate = useNavigate() + const dialogRef = useRef(null) + const { translate } = useInternationalization() + const [localData, setLocalData] = useState(undefined) + const stripeProvider = localData?.provider + const isEdition = !!stripeProvider + + const [addApiKey] = useAddStripeApiKeyMutation({ + onCompleted({ addStripePaymentProvider }) { + if (addStripePaymentProvider?.id) { + navigate( + generatePath(STRIPE_INTEGRATION_DETAILS_ROUTE, { + integrationId: addStripePaymentProvider.id, + }), + ) + + addToast({ + message: translate('text_62b1edddbf5f461ab9712743'), + severity: 'success', + }) + } + }, + }) + + const [updateApiKey] = useUpdateStripeApiKeyMutation({ + onCompleted({ updateStripePaymentProvider }) { + if (updateStripePaymentProvider?.id) { + addToast({ + message: translate('text_62b1edddbf5f461ab97126f6'), + severity: 'success', + }) + + dialogRef.current?.closeDialog() + } + }, + }) + + const [getStripeProviderByCode] = useGetProviderByCodeForStripeLazyQuery() + + const formikProps = useFormik({ + initialValues: { + secretKey: stripeProvider?.secretKey || '', + code: stripeProvider?.code || '', + name: stripeProvider?.name || '', + }, + validationSchema: object().shape({ + name: string(), + code: string().required(''), + secretKey: string().required(''), + }), + onSubmit: async ({ secretKey, ...values }, formikBag) => { + const res = await getStripeProviderByCode({ + context: { silentErrorCodes: [LagoApiError.NotFound] }, + variables: { + code: values.code, + }, + }) + const isNotAllowedToMutate = + (!!res.data?.paymentProvider?.id && !isEdition) || + (isEdition && + !!res.data?.paymentProvider?.id && + res.data?.paymentProvider?.id !== stripeProvider?.id) + + if (isNotAllowedToMutate) { + formikBag.setFieldError('code', translate('text_632a2d437e341dcc76817556')) + return + } + + if (isEdition) { + await updateApiKey({ + variables: { + input: { + id: stripeProvider?.id || '', + ...values, + }, + }, + }) + } else { + await addApiKey({ + variables: { + input: { secretKey, ...values }, + }, + }) + } + + dialogRef.current?.closeDialog() + }, + validateOnMount: true, + enableReinitialize: true, + }) + + useImperativeHandle(ref, () => ({ + openDialog: (data) => { + setLocalData(data) + dialogRef.current?.openDialog() + }, + closeDialog: () => dialogRef.current?.closeDialog(), + })) + + return ( + ( + + {isEdition && ( + + )} + - - )} - > - - + + )} + > + + + + - - - ) - }, -) + + + + + + ) +}) const Content = styled.div` margin-bottom: ${theme.spacing(8)}; + + > *:not(:last-child) { + margin-bottom: ${theme.spacing(6)}; + } +` + +const InlineInputs = styled.div` + display: flex; + flex-direction: row; + align-items: flex-start; + gap: ${theme.spacing(6)}; + + > * { + flex: 1; + } ` AddStripeDialog.displayName = 'AddStripeDialog' diff --git a/src/components/settings/integrations/DeleteAdyenIntegrationDialog.tsx b/src/components/settings/integrations/DeleteAdyenIntegrationDialog.tsx index 0aeb0edb0..38fc06069 100644 --- a/src/components/settings/integrations/DeleteAdyenIntegrationDialog.tsx +++ b/src/components/settings/integrations/DeleteAdyenIntegrationDialog.tsx @@ -1,55 +1,83 @@ import { gql } from '@apollo/client' -import { forwardRef } from 'react' -import { useNavigate } from 'react-router' +import { forwardRef, useImperativeHandle, useRef, useState } from 'react' -import { DialogRef, Typography } from '~/components/designSystem' import { WarningDialog, WarningDialogRef } from '~/components/WarningDialog' import { addToast } from '~/core/apolloClient' -import { INTEGRATIONS_ROUTE } from '~/core/router' -import { useDeleteAdyenMutation } from '~/generated/graphql' +import { + DeleteAdyenIntegrationDialogFragment, + useDeleteAdyenIntegrationMutation, +} from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' gql` - mutation deleteAdyen($input: DestroyPaymentProviderInput!) { + fragment DeleteAdyenIntegrationDialog on AdyenProvider { + id + name + } + + mutation deleteAdyenIntegration($input: DestroyPaymentProviderInput!) { destroyPaymentProvider(input: $input) { id } } ` -export interface DeleteAdyenIntegrationDialogRef extends WarningDialogRef {} +type TDeleteAdyenIntegrationDialogProps = { + provider: DeleteAdyenIntegrationDialogFragment | null + callback?: Function +} -interface DeleteAdyenIntegrationDialogProps { - id: string +export interface DeleteAdyenIntegrationDialogRef { + openDialog: ({ provider, callback }: TDeleteAdyenIntegrationDialogProps) => unknown + closeDialog: () => unknown } -export const DeleteAdyenIntegrationDialog = forwardRef< - DialogRef, - DeleteAdyenIntegrationDialogProps ->(({ id }: DeleteAdyenIntegrationDialogProps, ref) => { - const navigate = useNavigate() - const [deleteAdyen] = useDeleteAdyenMutation({ - onCompleted(data) { - if (data && data.destroyPaymentProvider) { - navigate(INTEGRATIONS_ROUTE) - addToast({ - message: translate('text_645d071272418a14c1c76b25'), - severity: 'success', - }) - } - }, - }) - const { translate } = useInternationalization() - - return ( - } - onContinue={async () => await deleteAdyen({ variables: { input: { id } } })} - continueText={translate('text_645d071272418a14c1c76a81')} - /> - ) -}) +export const DeleteAdyenIntegrationDialog = forwardRef( + (_, ref) => { + const { translate } = useInternationalization() + + const dialogRef = useRef(null) + const [localData, setLocalData] = useState( + undefined, + ) + const adyenProvider = localData?.provider + + const [deleteAdyen] = useDeleteAdyenIntegrationMutation({ + onCompleted(data) { + if (data && data.destroyPaymentProvider) { + dialogRef.current?.closeDialog() + localData?.callback?.() + addToast({ + message: translate('text_645d071272418a14c1c76b25'), + severity: 'success', + }) + } + }, + update(cache) { + cache.evict({ id: `AdyenProvider:${adyenProvider?.id}` }) + }, + }) + + useImperativeHandle(ref, () => ({ + openDialog: (data) => { + setLocalData(data) + dialogRef.current?.openDialog() + }, + closeDialog: () => dialogRef.current?.closeDialog(), + })) + + return ( + + await deleteAdyen({ variables: { input: { id: adyenProvider?.id as string } } }) + } + continueText={translate('text_645d071272418a14c1c76a81')} + /> + ) + }, +) DeleteAdyenIntegrationDialog.displayName = 'DeleteAdyenIntegrationDialog' diff --git a/src/components/settings/integrations/DeleteGocardlessIntegrationDialog.tsx b/src/components/settings/integrations/DeleteGocardlessIntegrationDialog.tsx new file mode 100644 index 000000000..a0856737a --- /dev/null +++ b/src/components/settings/integrations/DeleteGocardlessIntegrationDialog.tsx @@ -0,0 +1,85 @@ +import { gql } from '@apollo/client' +import { forwardRef, useImperativeHandle, useRef, useState } from 'react' + +import { WarningDialog, WarningDialogRef } from '~/components/WarningDialog' +import { addToast } from '~/core/apolloClient' +import { + DeleteGocardlessIntegrationDialogFragment, + useDeleteGocardlessMutation, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' + +gql` + fragment DeleteGocardlessIntegrationDialog on GocardlessProvider { + id + name + } + + mutation deleteGocardless($input: DestroyPaymentProviderInput!) { + destroyPaymentProvider(input: $input) { + id + } + } +` + +type TDeleteGocardlessIntegrationDialogProps = { + provider: DeleteGocardlessIntegrationDialogFragment | null + callback?: Function +} + +export interface DeleteGocardlessIntegrationDialogRef { + openDialog: ({ provider, callback }: TDeleteGocardlessIntegrationDialogProps) => unknown + closeDialog: () => unknown +} + +export const DeleteGocardlessIntegrationDialog = forwardRef( + (_, ref) => { + const { translate } = useInternationalization() + + const dialogRef = useRef(null) + const [localData, setLocalData] = useState( + undefined, + ) + + const gocardlessProvider = localData?.provider + + const [deleteGocardless] = useDeleteGocardlessMutation({ + onCompleted(data) { + if (data && data.destroyPaymentProvider) { + dialogRef.current?.closeDialog() + localData?.callback?.() + addToast({ + message: translate('text_62b1edddbf5f461ab9712758'), + severity: 'success', + }) + } + }, + update(cache) { + cache.evict({ id: `GocardlessProvider:${gocardlessProvider?.id}` }) + }, + }) + + useImperativeHandle(ref, () => ({ + openDialog: (data) => { + setLocalData(data) + dialogRef.current?.openDialog() + }, + closeDialog: () => dialogRef.current?.closeDialog(), + })) + + return ( + + await deleteGocardless({ variables: { input: { id: gocardlessProvider?.id as string } } }) + } + continueText={translate('text_659d5de7c9b7f51394f7f3fd')} + /> + ) + }, +) + +DeleteGocardlessIntegrationDialog.displayName = 'DeleteGocardlessIntegrationDialog' diff --git a/src/components/settings/integrations/DeleteStripeIntegrationDialog.tsx b/src/components/settings/integrations/DeleteStripeIntegrationDialog.tsx index b7879172d..ede06efec 100644 --- a/src/components/settings/integrations/DeleteStripeIntegrationDialog.tsx +++ b/src/components/settings/integrations/DeleteStripeIntegrationDialog.tsx @@ -1,15 +1,17 @@ import { gql } from '@apollo/client' -import { forwardRef } from 'react' -import { useNavigate } from 'react-router' +import { forwardRef, useImperativeHandle, useRef, useState } from 'react' -import { DialogRef, Typography } from '~/components/designSystem' import { WarningDialog, WarningDialogRef } from '~/components/WarningDialog' import { addToast } from '~/core/apolloClient' -import { INTEGRATIONS_ROUTE } from '~/core/router' -import { useDeleteStripeMutation } from '~/generated/graphql' +import { DeleteStripeIntegrationDialogFragment, useDeleteStripeMutation } from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' gql` + fragment DeleteStripeIntegrationDialog on StripeProvider { + id + name + } + mutation deleteStripe($input: DestroyPaymentProviderInput!) { destroyPaymentProvider(input: $input) { id @@ -17,39 +19,63 @@ gql` } ` -export interface DeleteStripeIntegrationDialogRef extends WarningDialogRef {} +type TDeleteStripeIntegrationDialogProps = { + provider: DeleteStripeIntegrationDialogFragment | null + callback?: Function +} -interface DeleteStripeIntegrationDialogProps { - id: string +export interface DeleteStripeIntegrationDialogRef { + openDialog: ({ provider, callback }: TDeleteStripeIntegrationDialogProps) => unknown + closeDialog: () => unknown } -export const DeleteStripeIntegrationDialog = forwardRef< - DialogRef, - DeleteStripeIntegrationDialogProps ->(({ id }: DeleteStripeIntegrationDialogProps, ref) => { - const navigate = useNavigate() - const [deleteStripe] = useDeleteStripeMutation({ - onCompleted(data) { - if (data && data.destroyPaymentProvider) { - navigate(INTEGRATIONS_ROUTE) - addToast({ - message: translate('text_62b1edddbf5f461ab9712758'), - severity: 'success', - }) - } - }, - }) - const { translate } = useInternationalization() - - return ( - } - onContinue={async () => await deleteStripe({ variables: { input: { id } } })} - continueText={translate('text_62b1edddbf5f461ab971270f')} - /> - ) -}) +export const DeleteStripeIntegrationDialog = forwardRef( + (_, ref) => { + const { translate } = useInternationalization() + + const dialogRef = useRef(null) + const [localData, setLocalData] = useState( + undefined, + ) + + const stripeProvider = localData?.provider + + const [deleteStripe] = useDeleteStripeMutation({ + onCompleted(data) { + if (data && data.destroyPaymentProvider) { + dialogRef.current?.closeDialog() + localData?.callback?.() + addToast({ + message: translate('text_62b1edddbf5f461ab9712758'), + severity: 'success', + }) + } + }, + update(cache) { + cache.evict({ id: `StripeProvider:${stripeProvider?.id}` }) + }, + }) + + useImperativeHandle(ref, () => ({ + openDialog: (data) => { + setLocalData(data) + dialogRef.current?.openDialog() + }, + closeDialog: () => dialogRef.current?.closeDialog(), + })) + + return ( + + await deleteStripe({ variables: { input: { id: stripeProvider?.id as string } } }) + } + continueText={translate('text_645d071272418a14c1c76a81')} + /> + ) + }, +) DeleteStripeIntegrationDialog.displayName = 'DeleteStripeIntegrationDialog' diff --git a/src/core/apolloClient/cacheUtils.ts b/src/core/apolloClient/cacheUtils.ts index a58b00a7e..5293598c5 100644 --- a/src/core/apolloClient/cacheUtils.ts +++ b/src/core/apolloClient/cacheUtils.ts @@ -16,6 +16,7 @@ gql` id organizations { id + name timezone } } @@ -56,7 +57,10 @@ export const onLogIn = (token: string, user: CurrentUserFragment) => { } // If still not organization, take the first one - if (!organization) organization = (user?.organizations || [])[0] + if (!organization) + organization = (user?.organizations || []).sort( + (a, b) => a.name.toLowerCase()?.localeCompare(b.name.toLowerCase() ?? '') ?? 0, + )[0] // Set the organization id in local storage setItemFromLS(ORGANIZATION_LS_KEY_ID, organization?.id) diff --git a/src/core/formats/__tests__/fixture.ts b/src/core/formats/__tests__/fixture.ts new file mode 100644 index 000000000..eb653a51f --- /dev/null +++ b/src/core/formats/__tests__/fixture.ts @@ -0,0 +1,6503 @@ +export const oneSubscription = [ + { + fromDatetime: '2024-01-01T00:00:00Z', + toDatetime: '2024-01-09T13:01:38Z', + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [ + { + id: 'f8f77c9c-ed1a-46e8-a3ef-d65a6a1db953', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '206', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + units: 6, + preciseUnitAmount: 0.343333333333333, + appliedTaxes: [ + { + id: 'f2b5077a-91c2-4dc2-b1e2-08660c4b9c20', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '1fb14cde-845a-4c1c-8729-6b8d8850aa9b', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated percentage', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated_percentage', + minAmountCents: '0', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitTotalAmount: '0.01', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '1.01', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitTotalAmount: '0.05', + rate: '1.0', + toValue: null, + totalWithFlatAmount: '1.05', + units: '5.0', + }, + ], + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '069a3be4-73bf-4d18-bfce-d6c74185d491', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '2903', + description: null, + feeType: 'subscription', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan', + units: 1, + preciseUnitAmount: 29.03, + appliedTaxes: [ + { + id: '19f72015-a550-41cf-8839-126538807aef', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: null, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '66dbd1ea-bf62-470c-9af2-8094f55b6ce2', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '700', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears volume', + itemName: 'Count BM', + units: 6, + preciseUnitAmount: 1.166666666666667, + appliedTaxes: [ + { + id: '27a3dac2-0ee6-48c6-8261-7f39286f8de6', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '2d7e977b-75a0-49dc-8ba6-33d1f3588b1f', + payInAdvance: false, + invoiceDisplayName: 'metered arrears volume', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'volume', + minAmountCents: '0', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: '1.0', + perUnitAmount: '1.0', + perUnitTotalAmount: '6.0', + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '907a7c26-08e7-41af-9d9f-863a5b7b83f6', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '800', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated', + itemName: 'Sum BM', + units: 6, + preciseUnitAmount: 1.333333333333333, + appliedTaxes: [ + { + id: '8bfe3b59-1547-4ff1-8a0e-787126d369e5', + taxRate: 25, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: 'ddbb9a53-cc4a-4d8e-a7ee-be7cc74fa51a', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + toValue: 1, + totalWithFlatAmount: '2.0', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitAmount: '1.0', + perUnitTotalAmount: '5.0', + toValue: null, + totalWithFlatAmount: '6.0', + units: '5.0', + }, + ], + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '8845bd12-14ff-4101-8022-194b9af0c773', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '200', + description: null, + feeType: 'charge', + groupName: 'france', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + units: 6, + preciseUnitAmount: 0.333333333333333, + appliedTaxes: [ + { + id: '0ce2df5f-ffe9-4695-8e1f-006df01ccf38', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: 'b21c33f9-e290-489f-a4b7-e2f86c5dfc77', + payInAdvance: false, + invoiceDisplayName: 'metered arrears package 1 dim', + billableMetric: { + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + aggregationType: 'count_agg', + }, + chargeModel: 'package', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'f74c847e-4ce5-49c4-824d-3e3291916be1', + key: null, + value: 'france', + }, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: '0.0', + paidUnits: '6.0', + perPackageSize: 10, + perPackageUnitAmount: '2.0', + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '32206e16-eaa9-4a54-9d14-5f16c8df063a', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '100', + description: null, + feeType: 'charge', + groupName: 'IT', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + units: 1, + preciseUnitAmount: 1, + appliedTaxes: [ + { + id: '9b75ac14-4287-4288-9b6c-169dc3a9c4b6', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: 'b21c33f9-e290-489f-a4b7-e2f86c5dfc77', + payInAdvance: false, + invoiceDisplayName: 'metered arrears package 1 dim', + billableMetric: { + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + aggregationType: 'count_agg', + }, + chargeModel: 'package', + minAmountCents: '0', + prorated: false, + subscriptions: {}, + }, + group: { + id: 'dc94ab8b-9a7c-4a57-8092-bd015eaa81a2', + key: null, + value: 'italy', + }, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: '0.0', + paidUnits: '1.0', + perPackageSize: 10, + perPackageUnitAmount: '1.0', + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '30eec11f-d336-44f1-b114-f6c7f51d92c9', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '605', + description: null, + feeType: 'charge', + groupName: 'AWS • europe', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 6, + preciseUnitAmount: 1.008333333333333, + appliedTaxes: [ + { + id: '5041eb21-813f-41e3-b4bf-a1ec25cb8e0c', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '4d98f89d-236a-4c4c-8b9d-7cd45a24430b', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: '2e3e9a2f-c052-44a7-a12b-a9cf4faf90a3', + key: 'AWS', + value: 'europe', + }, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.05', + freeUnits: '1.0', + paidUnits: '5.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '5.0', + fixedFeeUnitAmount: '1.0', + freeEvents: 1, + minMaxAdjustmentTotalAmount: '1.0', + paidEvents: 5, + rate: '1.0', + units: '6.0', + }, + }, + { + id: 'a088af7b-caa7-463c-b102-e770e618afcd', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '12', + description: null, + feeType: 'charge', + groupName: 'AWS • usa', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 6, + preciseUnitAmount: 0.02, + appliedTaxes: [ + { + id: '6ea398d9-0695-4a5c-b891-b7ba5245af88', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '4d98f89d-236a-4c4c-8b9d-7cd45a24430b', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: '23cce38b-919c-45d3-90a8-e860e0db5776', + key: 'AWS', + value: 'usa', + }, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.12', + freeUnits: '0.0', + paidUnits: '6.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 6, + rate: '2.0', + units: '6.0', + }, + }, + { + id: '9acd0bf9-193e-45fa-953f-ef3df74f7488', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '9', + description: null, + feeType: 'charge', + groupName: 'GOOOOOOOO USA!', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 6, + preciseUnitAmount: 0.015, + appliedTaxes: [ + { + id: '38e712da-8b36-48ca-83bf-d29a4f5f64c7', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '4d98f89d-236a-4c4c-8b9d-7cd45a24430b', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'a54a3ba0-b209-492d-956b-18c0a8ea7f23', + key: 'Google', + value: 'usa', + }, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.09', + freeUnits: '3.0', + paidUnits: '3.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 2, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 4, + rate: '3.0', + units: '6.0', + }, + }, + { + id: '06e0b486-d694-475a-b6a7-8d1554f4d12e', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '600', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears standard', + itemName: 'Sum BM', + units: 6, + preciseUnitAmount: 1, + appliedTaxes: [ + { + id: '130b2f46-480e-46f0-be8c-2f29621a7e62', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '686e24ba-7eb5-4256-92bf-7d0a11d53968', + payInAdvance: false, + invoiceDisplayName: 'metered arrears standard', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'standard', + minAmountCents: '0', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '5f604cdd-d096-482c-b997-6907bf0c16ab', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '600', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + units: 6, + preciseUnitAmount: 1, + appliedTaxes: [ + { + id: 'e92dc699-c0e6-4705-9496-9e16738dbf2e', + taxRate: 20, + }, + ], + trueUpFee: { + id: '231775c5-c7a5-4784-b728-c79c89196f7c', + }, + trueUpParentFee: null, + charge: { + id: '73f02087-9204-41e3-8b1d-30de231c200e', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage minimum spending', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'standard', + minAmountCents: '1100000', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '231775c5-c7a5-4784-b728-c79c89196f7c', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '318754', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + units: 1, + preciseUnitAmount: 3187.54, + appliedTaxes: [ + { + id: '6f4c8c90-a622-46b1-924e-36a7dc698fdb', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: { + id: '5f604cdd-d096-482c-b997-6907bf0c16ab', + }, + charge: { + id: '73f02087-9204-41e3-8b1d-30de231c200e', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage minimum spending', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'standard', + minAmountCents: '1100000', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'd475af54-e604-4ff8-ac51-b6597d4ff5bc', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '1000', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 10, + appliedTaxes: [ + { + id: '4b5aff80-1cd1-48a8-bb7d-28adcbd75a97', + taxRate: 20, + }, + ], + trueUpFee: { + id: '57109269-6eea-4edc-9dc4-8c97f09a4392', + }, + trueUpParentFee: null, + charge: { + id: '34398e7c-eecb-4e63-8aa5-d7a0211b974b', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '9999900', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '57109269-6eea-4edc-9dc4-8c97f09a4392', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '2902196', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 29021.96, + appliedTaxes: [ + { + id: '068c65bc-37b7-4665-ae14-98f8c55e2bc3', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: { + id: 'd475af54-e604-4ff8-ac51-b6597d4ff5bc', + }, + charge: { + id: '34398e7c-eecb-4e63-8aa5-d7a0211b974b', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '9999900', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'b95af8ba-a0f1-4a1b-aa81-7964904f5130', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '900', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'Count BM', + itemName: 'Count BM', + units: 6, + preciseUnitAmount: 1.5, + appliedTaxes: [ + { + id: '4f6b6f09-30d4-402d-b315-2b840626312a', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '0830cd9e-63de-45f9-9c8d-5c5e4550ee7f', + payInAdvance: false, + invoiceDisplayName: null, + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + toValue: 1, + totalWithFlatAmount: '2.0', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitAmount: '1.0', + perUnitTotalAmount: '2.0', + toValue: 3, + totalWithFlatAmount: '3.0', + units: '2.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 4, + perUnitAmount: '1.0', + perUnitTotalAmount: '3.0', + toValue: null, + totalWithFlatAmount: '4.0', + units: '3.0', + }, + ], + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + ], + }, +] + +export const oneSubscriptionResult = { + metadata: { + hasAnyFeeParsed: true, + }, + subscriptions: { + '59514df0-1abe-47dd-be36-445c9279240e': { + feesInAdvance: [], + feesInArrears: [ + { + amountCents: '2903', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '19f72015-a550-41cf-8839-126538807aef', + taxRate: 20, + }, + ], + charge: null, + description: null, + feeType: 'subscription', + group: null, + groupName: null, + id: '069a3be4-73bf-4d18-bfce-d6c74185d491', + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan', + metadata: { + displayName: 'Monthly subscription fee - maxi plan', + isSubscriptionFee: true, + }, + preciseUnitAmount: 29.03, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '900', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + toValue: 1, + totalWithFlatAmount: '2.0', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitAmount: '1.0', + perUnitTotalAmount: '2.0', + toValue: 3, + totalWithFlatAmount: '3.0', + units: '2.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 4, + perUnitAmount: '1.0', + perUnitTotalAmount: '3.0', + toValue: null, + totalWithFlatAmount: '4.0', + units: '3.0', + }, + ], + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '4f6b6f09-30d4-402d-b315-2b840626312a', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'graduated', + id: '0830cd9e-63de-45f9-9c8d-5c5e4550ee7f', + invoiceDisplayName: null, + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: 'b95af8ba-a0f1-4a1b-aa81-7964904f5130', + invoiceDisplayName: null, + invoiceName: 'Count BM', + itemName: 'Count BM', + metadata: { + displayName: 'Count BM', + isNormalFee: true, + }, + preciseUnitAmount: 1.5, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '800', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + toValue: 1, + totalWithFlatAmount: '2.0', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitAmount: '1.0', + perUnitTotalAmount: '5.0', + toValue: null, + totalWithFlatAmount: '6.0', + units: '5.0', + }, + ], + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '8bfe3b59-1547-4ff1-8a0e-787126d369e5', + taxRate: 25, + }, + ], + charge: { + billableMetric: { + aggregationType: 'sum_agg', + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + }, + chargeModel: 'graduated', + id: 'ddbb9a53-cc4a-4d8e-a7ee-be7cc74fa51a', + invoiceDisplayName: 'metered arrears graduated', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: '907a7c26-08e7-41af-9d9f-863a5b7b83f6', + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated', + itemName: 'Sum BM', + metadata: { + displayName: 'metered arrears graduated', + isNormalFee: true, + }, + preciseUnitAmount: 1.333333333333333, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '206', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitTotalAmount: '0.01', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '1.01', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitTotalAmount: '0.05', + rate: '1.0', + toValue: null, + totalWithFlatAmount: '1.05', + units: '5.0', + }, + ], + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'f2b5077a-91c2-4dc2-b1e2-08660c4b9c20', + taxRate: 0, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'graduated_percentage', + id: '1fb14cde-845a-4c1c-8729-6b8d8850aa9b', + invoiceDisplayName: 'metered arrears graduated percentage', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: 'f8f77c9c-ed1a-46e8-a3ef-d65a6a1db953', + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears graduated percentage', + isNormalFee: true, + }, + preciseUnitAmount: 0.343333333333333, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '200', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: '0.0', + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: '6.0', + perPackageSize: 10, + perPackageUnitAmount: '2.0', + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '0ce2df5f-ffe9-4695-8e1f-006df01ccf38', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + }, + chargeModel: 'package', + id: 'b21c33f9-e290-489f-a4b7-e2f86c5dfc77', + invoiceDisplayName: 'metered arrears package 1 dim', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: { + id: 'f74c847e-4ce5-49c4-824d-3e3291916be1', + key: null, + value: 'france', + }, + groupName: 'france', + id: '8845bd12-14ff-4101-8022-194b9af0c773', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + metadata: { + displayName: 'metered arrears package 1 dim • france', + isGroupChildFee: true, + }, + preciseUnitAmount: 0.333333333333333, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '100', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: '0.0', + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: '1.0', + perPackageSize: 10, + perPackageUnitAmount: '1.0', + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '9b75ac14-4287-4288-9b6c-169dc3a9c4b6', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + }, + chargeModel: 'package', + id: 'b21c33f9-e290-489f-a4b7-e2f86c5dfc77', + invoiceDisplayName: 'metered arrears package 1 dim', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + subscriptions: {}, + }, + description: null, + feeType: 'charge', + group: { + id: 'dc94ab8b-9a7c-4a57-8092-bd015eaa81a2', + key: null, + value: 'italy', + }, + groupName: 'IT', + id: '32206e16-eaa9-4a54-9d14-5f16c8df063a', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + metadata: { + displayName: 'metered arrears package 1 dim • IT', + isGroupChildFee: true, + }, + preciseUnitAmount: 1, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '605', + amountDetails: { + fixedFeeTotalAmount: '5.0', + fixedFeeUnitAmount: '1.0', + flatUnitAmount: null, + freeEvents: 1, + freeUnits: '1.0', + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: '1.0', + paidEvents: 5, + paidUnits: '5.0', + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.05', + rate: '1.0', + units: '6.0', + }, + appliedTaxes: [ + { + id: '5041eb21-813f-41e3-b4bf-a1ec25cb8e0c', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + }, + chargeModel: 'percentage', + id: '4d98f89d-236a-4c4c-8b9d-7cd45a24430b', + invoiceDisplayName: 'metered arrears percentage 2 dim', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: { + id: '2e3e9a2f-c052-44a7-a12b-a9cf4faf90a3', + key: 'AWS', + value: 'europe', + }, + groupName: 'AWS • europe', + id: '30eec11f-d336-44f1-b114-f6c7f51d92c9', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + metadata: { + displayName: 'metered arrears percentage 2 dim • AWS • europe', + isGroupChildFee: true, + }, + preciseUnitAmount: 1.008333333333333, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '12', + amountDetails: { + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + flatUnitAmount: null, + freeEvents: 0, + freeUnits: '0.0', + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 6, + paidUnits: '6.0', + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.12', + rate: '2.0', + units: '6.0', + }, + appliedTaxes: [ + { + id: '6ea398d9-0695-4a5c-b891-b7ba5245af88', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + }, + chargeModel: 'percentage', + id: '4d98f89d-236a-4c4c-8b9d-7cd45a24430b', + invoiceDisplayName: 'metered arrears percentage 2 dim', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: { + id: '23cce38b-919c-45d3-90a8-e860e0db5776', + key: 'AWS', + value: 'usa', + }, + groupName: 'AWS • usa', + id: 'a088af7b-caa7-463c-b102-e770e618afcd', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + metadata: { + displayName: 'metered arrears percentage 2 dim • AWS • usa', + isGroupChildFee: true, + }, + preciseUnitAmount: 0.02, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '9', + amountDetails: { + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + flatUnitAmount: null, + freeEvents: 2, + freeUnits: '3.0', + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 4, + paidUnits: '3.0', + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.09', + rate: '3.0', + units: '6.0', + }, + appliedTaxes: [ + { + id: '38e712da-8b36-48ca-83bf-d29a4f5f64c7', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + }, + chargeModel: 'percentage', + id: '4d98f89d-236a-4c4c-8b9d-7cd45a24430b', + invoiceDisplayName: 'metered arrears percentage 2 dim', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: { + id: 'a54a3ba0-b209-492d-956b-18c0a8ea7f23', + key: 'Google', + value: 'usa', + }, + groupName: 'GOOOOOOOO USA!', + id: '9acd0bf9-193e-45fa-953f-ef3df74f7488', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + metadata: { + displayName: 'metered arrears percentage 2 dim • GOOOOOOOO USA!', + isGroupChildFee: true, + }, + preciseUnitAmount: 0.015, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '600', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'e92dc699-c0e6-4705-9496-9e16738dbf2e', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'standard', + id: '73f02087-9204-41e3-8b1d-30de231c200e', + invoiceDisplayName: 'metered arrears percentage minimum spending', + minAmountCents: '1100000', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: '5f604cdd-d096-482c-b997-6907bf0c16ab', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears percentage minimum spending', + isNormalFee: true, + }, + preciseUnitAmount: 1, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: { + id: '231775c5-c7a5-4784-b728-c79c89196f7c', + }, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '318754', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '6f4c8c90-a622-46b1-924e-36a7dc698fdb', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'standard', + id: '73f02087-9204-41e3-8b1d-30de231c200e', + invoiceDisplayName: 'metered arrears percentage minimum spending', + minAmountCents: '1100000', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: '231775c5-c7a5-4784-b728-c79c89196f7c', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears percentage minimum spending', + isTrueUpFee: true, + }, + preciseUnitAmount: 3187.54, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: { + id: '5f604cdd-d096-482c-b997-6907bf0c16ab', + }, + units: 1, + }, + { + amountCents: '600', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '130b2f46-480e-46f0-be8c-2f29621a7e62', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'sum_agg', + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + }, + chargeModel: 'standard', + id: '686e24ba-7eb5-4256-92bf-7d0a11d53968', + invoiceDisplayName: 'metered arrears standard', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: '06e0b486-d694-475a-b6a7-8d1554f4d12e', + invoiceDisplayName: null, + invoiceName: 'metered arrears standard', + itemName: 'Sum BM', + metadata: { + displayName: 'metered arrears standard', + isNormalFee: true, + }, + preciseUnitAmount: 1, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '700', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: '1.0', + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: '1.0', + perUnitTotalAmount: '6.0', + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '27a3dac2-0ee6-48c6-8261-7f39286f8de6', + taxRate: 0, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'volume', + id: '2d7e977b-75a0-49dc-8ba6-33d1f3588b1f', + invoiceDisplayName: 'metered arrears volume', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: '66dbd1ea-bf62-470c-9af2-8094f55b6ce2', + invoiceDisplayName: null, + invoiceName: 'metered arrears volume', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears volume', + isNormalFee: true, + }, + preciseUnitAmount: 1.166666666666667, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + { + amountCents: '1000', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '4b5aff80-1cd1-48a8-bb7d-28adcbd75a97', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '34398e7c-eecb-4e63-8aa5-d7a0211b974b', + invoiceDisplayName: '', + minAmountCents: '9999900', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: 'd475af54-e604-4ff8-ac51-b6597d4ff5bc', + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + metadata: { + displayName: 'rec count', + isNormalFee: true, + }, + preciseUnitAmount: 10, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: { + id: '57109269-6eea-4edc-9dc4-8c97f09a4392', + }, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '2902196', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '068c65bc-37b7-4665-ae14-98f8c55e2bc3', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '34398e7c-eecb-4e63-8aa5-d7a0211b974b', + invoiceDisplayName: '', + minAmountCents: '9999900', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: '57109269-6eea-4edc-9dc4-8c97f09a4392', + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + metadata: { + displayName: 'rec count', + isTrueUpFee: true, + }, + preciseUnitAmount: 29021.96, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: { + id: 'd475af54-e604-4ff8-ac51-b6597d4ff5bc', + }, + units: 1, + }, + ], + metadata: { + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + differentBoundariesForSubscriptionAndCharges: false, + fromDatetime: '2024-01-01T00:00:00Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscriptionDisplayName: 'maxi plan', + toDatetime: '2024-01-09T13:01:38Z', + }, + }, + }, +} + +export const twoSubscriptions = [ + { + fromDatetime: '2024-01-01T00:00:00Z', + toDatetime: '2024-01-09T13:01:38Z', + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [ + { + id: 'f8f77c9c-ed1a-46e8-a3ef-d65a6a1db953', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '206', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + units: 6, + preciseUnitAmount: 0.343333333333333, + appliedTaxes: [ + { + id: 'f2b5077a-91c2-4dc2-b1e2-08660c4b9c20', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '1fb14cde-845a-4c1c-8729-6b8d8850aa9b', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated percentage', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated_percentage', + minAmountCents: '0', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitTotalAmount: '0.01', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '1.01', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitTotalAmount: '0.05', + rate: '1.0', + toValue: null, + totalWithFlatAmount: '1.05', + units: '5.0', + }, + ], + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + ], + }, + { + fromDatetime: '2024-01-01T00:00:00Z', + toDatetime: '2024-01-09T13:01:38Z', + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e2', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [ + { + id: 'f8f77c9c-ed1a-46e8-a3ef-d65a6a1db953', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e2', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '206', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + units: 6, + preciseUnitAmount: 0.343333333333333, + appliedTaxes: [ + { + id: 'f2b5077a-91c2-4dc2-b1e2-08660c4b9c20', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '1fb14cde-845a-4c1c-8729-6b8d8850aa9b', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated percentage', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated_percentage', + minAmountCents: '0', + prorated: false, + }, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitTotalAmount: '0.01', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '1.01', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitTotalAmount: '0.05', + rate: '1.0', + toValue: null, + totalWithFlatAmount: '1.05', + units: '5.0', + }, + ], + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + ], + }, +] + +export const twoSubscriptionsResult = { + metadata: { + hasAnyFeeParsed: true, + }, + subscriptions: { + '59514df0-1abe-47dd-be36-445c9279240e': { + feesInAdvance: [], + feesInArrears: [ + { + amountCents: '206', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitTotalAmount: '0.01', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '1.01', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitTotalAmount: '0.05', + rate: '1.0', + toValue: null, + totalWithFlatAmount: '1.05', + units: '5.0', + }, + ], + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'f2b5077a-91c2-4dc2-b1e2-08660c4b9c20', + taxRate: 0, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'graduated_percentage', + id: '1fb14cde-845a-4c1c-8729-6b8d8850aa9b', + invoiceDisplayName: 'metered arrears graduated percentage', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: 'f8f77c9c-ed1a-46e8-a3ef-d65a6a1db953', + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears graduated percentage', + isNormalFee: true, + }, + preciseUnitAmount: 0.343333333333333, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + ], + metadata: { + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + differentBoundariesForSubscriptionAndCharges: false, + fromDatetime: '2024-01-01T00:00:00Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscriptionDisplayName: 'maxi plan', + toDatetime: '2024-01-09T13:01:38Z', + }, + }, + '59514df0-1abe-47dd-be36-445c9279240e2': { + feesInAdvance: [], + feesInArrears: [ + { + amountCents: '206', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '1.0', + fromValue: 0, + perUnitTotalAmount: '0.01', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '1.01', + units: '1.0', + }, + { + flatUnitAmount: '1.0', + fromValue: 2, + perUnitTotalAmount: '0.05', + rate: '1.0', + toValue: null, + totalWithFlatAmount: '1.05', + units: '5.0', + }, + ], + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'f2b5077a-91c2-4dc2-b1e2-08660c4b9c20', + taxRate: 0, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'graduated_percentage', + id: '1fb14cde-845a-4c1c-8729-6b8d8850aa9b', + invoiceDisplayName: 'metered arrears graduated percentage', + minAmountCents: '0', + payInAdvance: false, + prorated: false, + }, + description: null, + feeType: 'charge', + group: null, + groupName: null, + id: 'f8f77c9c-ed1a-46e8-a3ef-d65a6a1db953', + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears graduated percentage', + isNormalFee: true, + }, + preciseUnitAmount: 0.343333333333333, + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e2', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 6, + }, + ], + metadata: { + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + differentBoundariesForSubscriptionAndCharges: false, + fromDatetime: '2024-01-01T00:00:00Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscriptionDisplayName: 'maxi plan', + toDatetime: '2024-01-09T13:01:38Z', + }, + }, + }, +} + +export const noFees = [ + { + fromDatetime: '2024-01-01T00:00:00Z', + toDatetime: '2024-01-09T13:01:38Z', + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [], + }, +] + +export const noFeesResult = { + metadata: { hasAnyFeeParsed: false }, + subscriptions: { + '59514df0-1abe-47dd-be36-445c9279240e': { + feesInAdvance: [], + feesInArrears: [], + metadata: { + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + differentBoundariesForSubscriptionAndCharges: false, + fromDatetime: '2024-01-01T00:00:00Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscriptionDisplayName: 'maxi plan', + toDatetime: '2024-01-09T13:01:38Z', + }, + }, + }, +} +export const subZeroAmount = [ + { + fromDatetime: '2024-01-01T00:00:00Z', + toDatetime: '2024-01-09T13:01:38Z', + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [ + { + id: '069a3be4-73bf-4d18-bfce-d6c74185d491', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'subscription', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan', + units: 1, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '19f72015-a550-41cf-8839-126538807aef', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: null, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + ], + }, +] + +export const chargeZeroAmount = [ + { + fromDatetime: '2024-01-01T00:00:00Z', + toDatetime: '2024-01-09T13:01:38Z', + chargesFromDatetime: '2024-01-01T00:00:00Z', + chargesToDatetime: '2024-01-09T13:01:38Z', + differentBoundariesForSubscriptionAndCharges: false, + inAdvanceChargesFromDatetime: '2024-01-01T00:00:00+00:00', + inAdvanceChargesToDatetime: '2024-01-09T00:00:00+00:00', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [ + { + id: '069a3be4-73bf-4d18-bfce-d6c74185d491', + subscription: { + id: '59514df0-1abe-47dd-be36-445c9279240e', + name: '', + plan: { + id: 'da8abf9d-022f-482c-a949-466c0131e080', + name: 'maxi plan', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'subscription', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '19f72015-a550-41cf-8839-126538807aef', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: null, + group: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + ], + }, +] + +export const unorderedSubscriptionWithFees = [ + { + fromDatetime: '2024-03-01T00:00:00Z', + toDatetime: '2024-03-31T23:59:59Z', + chargesFromDatetime: '2024-02-01T00:00:00Z', + chargesToDatetime: '2024-02-29T23:59:59Z', + inAdvanceChargesFromDatetime: null, + inAdvanceChargesToDatetime: null, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [ + { + id: '077afb3e-b1b5-45e7-9151-afd608b89766', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '63a6de02-1794-4fc4-8b5a-ae7683155d5a', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '6e40b8bf-b9f3-447f-9bd3-14e6b3be3cd0', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated percentage', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated_percentage', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '0.0', + fromValue: 0, + perUnitTotalAmount: '0.0', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '0.0', + units: '0.0', + }, + ], + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '9eab70e0-c840-4fc3-aad0-0d445241ba88', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears volume', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '8877b6f0-24d7-422d-aadf-e08f8a33d7c2', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '06b2b65b-b1a7-4e43-82fc-dc5ed9738b3c', + payInAdvance: false, + invoiceDisplayName: 'metered arrears volume', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'volume', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: '0.0', + perUnitAmount: '0.0', + perUnitTotalAmount: '0.0', + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '817ea1cc-f47b-4b48-806f-6a0ce03747a1', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '10000', + description: null, + feeType: 'subscription', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan sub arrears', + units: 1, + preciseUnitAmount: 100, + appliedTaxes: [ + { + id: '03241fa4-63d6-4dfe-b038-8e6c7ba27e99', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: null, + group: null, + eventsCount: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'd354a597-5bf4-4a3c-89c3-6ce16ec7406d', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated', + itemName: 'Sum BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '1f2b9996-c3e4-4946-ba5d-471a8d7c90f0', + taxRate: 25, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '05df220f-85dd-41a2-a0c3-dc5cc0eef533', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: [ + { + flatUnitAmount: '0.0', + fromValue: 0, + perUnitAmount: '0.0', + perUnitTotalAmount: '0.0', + toValue: 1, + totalWithFlatAmount: '0.0', + units: '0.0', + }, + ], + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '27d61806-c220-42dd-befd-a90c4f652ff4', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'france', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '87af0e98-1ba3-470b-986c-d85a0d959129', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '9ed0da11-0c27-4c45-a5a2-ae1a64e00cea', + payInAdvance: false, + invoiceDisplayName: 'metered arrears package 1 dim', + billableMetric: { + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + aggregationType: 'count_agg', + }, + chargeModel: 'package', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'f74c847e-4ce5-49c4-824d-3e3291916be1', + key: null, + value: 'france', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: 0, + perPackageUnitAmount: '0.0', + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'ed477cf0-5459-43f7-9cd3-f5262519a26d', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'IT', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '4e16e526-27d8-422f-aa33-035ed2d396bd', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '9ed0da11-0c27-4c45-a5a2-ae1a64e00cea', + payInAdvance: false, + invoiceDisplayName: 'metered arrears package 1 dim', + billableMetric: { + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + aggregationType: 'count_agg', + }, + chargeModel: 'package', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'dc94ab8b-9a7c-4a57-8092-bd015eaa81a2', + key: null, + value: 'italy', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: 0, + perPackageUnitAmount: '0.0', + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '98f1c632-ff4d-4e4e-86a0-28748321a662', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'AWS • europe', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'f8612c1d-ffd1-4876-8471-381b0b84d143', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '25b455e4-1333-4c76-afc3-7398e5d58892', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: '2e3e9a2f-c052-44a7-a12b-a9cf4faf90a3', + key: 'AWS', + value: 'europe', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '1.0', + units: '0.0', + }, + }, + { + id: 'cb1bf837-e4f7-4112-b532-eacc2b36317e', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'AWS • usa', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'd606c4a1-ac30-482e-89fb-b6a2ee7c2d57', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '25b455e4-1333-4c76-afc3-7398e5d58892', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: '23cce38b-919c-45d3-90a8-e860e0db5776', + key: 'AWS', + value: 'usa', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '2.0', + units: '0.0', + }, + }, + { + id: '8e699c82-e254-4197-a8d6-5e9a5170d778', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'GOOOOOOOO USA!', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '57b53d82-91bf-4a53-94bf-e4c9714a52e7', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '25b455e4-1333-4c76-afc3-7398e5d58892', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'a54a3ba0-b209-492d-956b-18c0a8ea7f23', + key: 'Google', + value: 'usa', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '3.0', + units: '0.0', + }, + }, + { + id: '82d7195a-1e42-4c86-930f-859a43b1693e', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears standard', + itemName: 'Sum BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'b02f802a-bc06-4738-9573-553fbc4653d5', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '8c17937b-d5b5-42ab-bb6e-6b89651564db', + payInAdvance: false, + invoiceDisplayName: 'metered arrears standard', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'standard', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '061e4abe-9e92-4477-b5fb-987304f16735', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '219b207a-ff39-4284-922f-0009deef66ca', + taxRate: 20, + }, + ], + trueUpFee: { + id: '72dbfa60-2cf4-43d7-9884-8107ada8d60a', + }, + trueUpParentFee: null, + charge: { + id: '34e6b422-b03e-4512-9778-93c1ad465c21', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage minimum spending', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'standard', + minAmountCents: '1100000', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '72dbfa60-2cf4-43d7-9884-8107ada8d60a', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '1100000', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + units: 1, + preciseUnitAmount: 11000, + appliedTaxes: [ + { + id: 'cebee521-58f7-4dfd-919e-cd51e3ccd8fc', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: { + id: '061e4abe-9e92-4477-b5fb-987304f16735', + }, + charge: { + id: '34e6b422-b03e-4512-9778-93c1ad465c21', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage minimum spending', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'standard', + minAmountCents: '1100000', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'f9aeb27c-4261-495b-86cb-c4ebea335ca5', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '1000', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 10, + appliedTaxes: [ + { + id: 'e3e9793f-0f4c-4e6a-ae92-1f0f24658f38', + taxRate: 20, + }, + ], + trueUpFee: { + id: 'cff1026b-baec-4fe2-a725-99532769865a', + }, + trueUpParentFee: null, + charge: { + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '9999900', + prorated: false, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'cff1026b-baec-4fe2-a725-99532769865a', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '9998900', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 99989, + appliedTaxes: [ + { + id: 'baddf7d2-f84c-4424-a970-d0e9075eb0b3', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: { + id: 'f9aeb27c-4261-495b-86cb-c4ebea335ca5', + }, + charge: { + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '9999900', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'a54a6f27-ac59-45b7-bc0d-4a42415c1e47', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '66700', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count prorated advance', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 667, + appliedTaxes: [ + { + id: 'ea35ee38-2d5f-4453-8a87-ba7a92269837', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '054ca896-1e1c-4190-ad42-eed7c24b9270', + payInAdvance: true, + invoiceDisplayName: 'rec count prorated advance', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '0', + prorated: true, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'cc0dc739-46f6-41a8-94f3-284d07d2c4c7', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'Count BM', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'a4358d5c-77e0-4173-9b12-342763a72a03', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '34fd251e-7210-410d-ab87-91b77a6a075b', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: [ + { + flatUnitAmount: '0.0', + fromValue: 0, + perUnitAmount: '0.0', + perUnitTotalAmount: '0.0', + toValue: 1, + totalWithFlatAmount: '0.0', + units: '0.0', + }, + ], + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '1d19eec2-3ba6-49bc-8767-66f8e4b8b83a', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '200', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count prorated graduated', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 2, + appliedTaxes: [ + { + id: '1c1b3281-73e7-4113-a3de-650f462b0157', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: 'bc29cfb6-998f-422d-858f-6107dd905530', + payInAdvance: false, + invoiceDisplayName: 'rec count prorated graduated', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: true, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '2398dd5c-6558-45df-b97c-3e913f79c3ea', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '200', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count prorated volume', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 2, + appliedTaxes: [ + { + id: '83e835ea-ae89-4a1e-aa49-3d48286262d9', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '5575dc4f-f78c-4491-8ef0-9c778f1b4435', + payInAdvance: false, + invoiceDisplayName: 'rec count prorated volume', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'volume', + minAmountCents: '0', + prorated: true, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: '1.0', + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '7b1557a9-5b94-4d2a-b453-a1f749fc27e3', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'Sum BM', + itemName: 'Sum BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '4effc63f-c169-4ede-8dc7-6e9e23154dc3', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '422e93d6-1c10-4339-b327-2a3ca61581f5', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '11.0', + units: '0.0', + }, + }, + { + id: '9032acd1-a5c4-4c80-b500-94700d997d32', + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '9999900', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'Advance recurring', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 99999, + appliedTaxes: [ + { + id: '7375835a-359d-4740-b8f7-a4d8c823ccb7', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '0fc08fb5-7cc1-43bd-a7d2-d3fac8835d0c', + payInAdvance: true, + invoiceDisplayName: 'Advance recurring', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + ], + }, + { + fromDatetime: '2024-03-11T00:00:00Z', + toDatetime: '2024-04-10T23:59:59Z', + chargesFromDatetime: '2024-02-11T00:00:00Z', + chargesToDatetime: '2024-03-10T23:59:59Z', + inAdvanceChargesFromDatetime: null, + inAdvanceChargesToDatetime: null, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + interval: 'monthly', + amountCents: '10000', + amountCurrency: 'EUR', + invoiceDisplayName: 'sub fee', + }, + }, + fees: [ + { + id: '626e9246-f986-4aa1-b586-3501f5b50dbc', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '10000', + description: null, + feeType: 'subscription', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan sub arrears', + units: 1, + preciseUnitAmount: 100, + appliedTaxes: [ + { + id: 'de9197a3-4919-40ca-85cf-4db578fd1961', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: null, + group: null, + eventsCount: null, + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'cf0be687-7268-4466-ba0e-3fc147ad584a', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated percentage', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'e5d5a002-578c-4bfb-85f8-3e8ea813fbb5', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '6e40b8bf-b9f3-447f-9bd3-14e6b3be3cd0', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated percentage', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated_percentage', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: [ + { + flatUnitAmount: '0.0', + fromValue: 0, + perUnitTotalAmount: '0.0', + rate: '1.0', + toValue: 1, + totalWithFlatAmount: '0.0', + units: '0.0', + }, + ], + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '0a531d59-12d6-4804-a656-08cdd280b5df', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'france', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '208270ae-38e5-4e41-a0f1-cd06a89271bd', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '9ed0da11-0c27-4c45-a5a2-ae1a64e00cea', + payInAdvance: false, + invoiceDisplayName: 'metered arrears package 1 dim', + billableMetric: { + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + aggregationType: 'count_agg', + }, + chargeModel: 'package', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'f74c847e-4ce5-49c4-824d-3e3291916be1', + key: null, + value: 'france', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: 0, + perPackageUnitAmount: '0.0', + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '9cd55b8d-380d-425c-a35d-8afd0f971b7b', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears volume', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'afd99c92-ae12-44af-97bb-07fae721af40', + taxRate: 0, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '06b2b65b-b1a7-4e43-82fc-dc5ed9738b3c', + payInAdvance: false, + invoiceDisplayName: 'metered arrears volume', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'volume', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: '0.0', + perUnitAmount: '0.0', + perUnitTotalAmount: '0.0', + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'f1d47378-4850-419c-a296-b31f727a2da5', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears graduated', + itemName: 'Sum BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '2ec49341-adb2-4815-9f5c-ab82947060e9', + taxRate: 25, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '05df220f-85dd-41a2-a0c3-dc5cc0eef533', + payInAdvance: false, + invoiceDisplayName: 'metered arrears graduated', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: [ + { + flatUnitAmount: '0.0', + fromValue: 0, + perUnitAmount: '0.0', + perUnitTotalAmount: '0.0', + toValue: 1, + totalWithFlatAmount: '0.0', + units: '0.0', + }, + ], + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'a06ae8ab-d600-4745-ba0e-fa600496241f', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'IT', + invoiceDisplayName: null, + invoiceName: 'metered arrears package 1 dim', + itemName: 'Count BM - One dimension', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '76c3feef-b010-4215-8730-5ffaeba16568', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '9ed0da11-0c27-4c45-a5a2-ae1a64e00cea', + payInAdvance: false, + invoiceDisplayName: 'metered arrears package 1 dim', + billableMetric: { + id: 'e78c6d05-db1c-4485-b82c-fc5c056d19be', + name: 'Count BM - One dimension', + aggregationType: 'count_agg', + }, + chargeModel: 'package', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'dc94ab8b-9a7c-4a57-8092-bd015eaa81a2', + key: null, + value: 'italy', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: 0, + perPackageUnitAmount: '0.0', + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '3b34a414-1c11-412a-848a-a4e6df9a9226', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'AWS • europe', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'adcda98c-48ac-4a5a-b921-886a399b1935', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '25b455e4-1333-4c76-afc3-7398e5d58892', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: '2e3e9a2f-c052-44a7-a12b-a9cf4faf90a3', + key: 'AWS', + value: 'europe', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '1.0', + units: '0.0', + }, + }, + { + id: 'ff612e87-40f9-4a24-a533-21778d3ada20', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'AWS • usa', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '1315f59e-0a8f-45ec-831c-dc528f0e0d0b', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '25b455e4-1333-4c76-afc3-7398e5d58892', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: '23cce38b-919c-45d3-90a8-e860e0db5776', + key: 'AWS', + value: 'usa', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '2.0', + units: '0.0', + }, + }, + { + id: '9b96d481-e2b8-4eff-aa1d-1fd2190aad88', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: 'GOOOOOOOO USA!', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage 2 dim', + itemName: 'Count BM - Two dimensions', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '6b2c58c1-87a7-405f-8402-59b163a41d10', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '25b455e4-1333-4c76-afc3-7398e5d58892', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage 2 dim', + billableMetric: { + id: '1bcd941b-6ac4-4849-a4b8-7c793f6cebad', + name: 'Count BM - Two dimensions', + aggregationType: 'count_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: { + id: 'a54a3ba0-b209-492d-956b-18c0a8ea7f23', + key: 'Google', + value: 'usa', + }, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '3.0', + units: '0.0', + }, + }, + { + id: '9208414b-4ec3-46c8-9930-bb10a7086d8e', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears standard', + itemName: 'Sum BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'e3fe0ef6-9ce1-4fbe-9e29-62bccd244b16', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '8c17937b-d5b5-42ab-bb6e-6b89651564db', + payInAdvance: false, + invoiceDisplayName: 'metered arrears standard', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'standard', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '1acab4b6-1f30-450f-b87a-02dbf2ce31ec', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '21cc7b6a-84e1-47a8-8450-507bfc403611', + taxRate: 20, + }, + ], + trueUpFee: { + id: '599299c4-7519-44f6-9a48-26814677e2e0', + }, + trueUpParentFee: null, + charge: { + id: '34e6b422-b03e-4512-9778-93c1ad465c21', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage minimum spending', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'standard', + minAmountCents: '1100000', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '599299c4-7519-44f6-9a48-26814677e2e0', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '1100000', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + units: 1, + preciseUnitAmount: 11000, + appliedTaxes: [ + { + id: 'ee18bd57-db30-4ea9-9640-24b1ca7ffd9a', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: { + id: '1acab4b6-1f30-450f-b87a-02dbf2ce31ec', + }, + charge: { + id: '34e6b422-b03e-4512-9778-93c1ad465c21', + payInAdvance: false, + invoiceDisplayName: 'metered arrears percentage minimum spending', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'standard', + minAmountCents: '1100000', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'cc82649b-37b5-4be2-9068-43665288a1d4', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '1000', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 10, + appliedTaxes: [ + { + id: 'ee77a4ee-4013-4d74-8830-8cb2fb68fabb', + taxRate: 20, + }, + ], + trueUpFee: { + id: '161c7a55-a56e-4f38-8009-ae6a3bd29edc', + }, + trueUpParentFee: null, + charge: { + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '9999900', + prorated: false, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '161c7a55-a56e-4f38-8009-ae6a3bd29edc', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '9998900', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 99989, + appliedTaxes: [ + { + id: '8d47e1e3-8f75-446d-8c14-f8ba3b58c095', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: { + id: 'cc82649b-37b5-4be2-9068-43665288a1d4', + }, + charge: { + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '9999900', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '86ee400c-a0c5-4e7b-a6c4-0915a7296fcd', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '66700', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count prorated advance', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 667, + appliedTaxes: [ + { + id: 'ec8d1e3c-6cee-40f4-8e4a-70850ceecded', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '054ca896-1e1c-4190-ad42-eed7c24b9270', + payInAdvance: true, + invoiceDisplayName: 'rec count prorated advance', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '0', + prorated: true, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'c3b7bb85-cdde-4511-8e91-76491fcb51b8', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'Count BM', + itemName: 'Count BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: '4318e992-6cd8-4030-8209-ecaa131a50e9', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '34fd251e-7210-410d-ab87-91b77a6a075b', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + aggregationType: 'count_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: [ + { + flatUnitAmount: '0.0', + fromValue: 0, + perUnitAmount: '0.0', + perUnitTotalAmount: '0.0', + toValue: 1, + totalWithFlatAmount: '0.0', + units: '0.0', + }, + ], + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: 'c94363c5-6f45-490e-8b9f-7c4c41cd725e', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '200', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count prorated graduated', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 2, + appliedTaxes: [ + { + id: 'a0c2fc7c-c091-465a-8133-83c292557770', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: 'bc29cfb6-998f-422d-858f-6107dd905530', + payInAdvance: false, + invoiceDisplayName: 'rec count prorated graduated', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'graduated', + minAmountCents: '0', + prorated: true, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '609a8c7a-756d-4468-a70b-a270183b22b7', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '200', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'rec count prorated volume', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 2, + appliedTaxes: [ + { + id: '52a03e29-7a8c-445d-a143-579f38a84bf3', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '5575dc4f-f78c-4491-8ef0-9c778f1b4435', + payInAdvance: false, + invoiceDisplayName: 'rec count prorated volume', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'volume', + minAmountCents: '0', + prorated: true, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: '1.0', + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + { + id: '5e6acf8d-c7af-4c52-94ae-ad2784a25ad0', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '0', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'Sum BM', + itemName: 'Sum BM', + units: 0, + preciseUnitAmount: 0, + appliedTaxes: [ + { + id: 'de7d66ad-b9ca-464f-92da-ba2d4dba0609', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '422e93d6-1c10-4339-b327-2a3ca61581f5', + payInAdvance: false, + invoiceDisplayName: '', + billableMetric: { + id: '869d5637-5eb3-40db-8dbc-a87b8cd7a3f8', + name: 'Sum BM', + aggregationType: 'sum_agg', + }, + chargeModel: 'percentage', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '0', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: '0.0', + freeUnits: '0.0', + paidUnits: '0.0', + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: '0.0', + fixedFeeUnitAmount: '0.0', + freeEvents: 0, + minMaxAdjustmentTotalAmount: '0.0', + paidEvents: 0, + rate: '11.0', + units: '0.0', + }, + }, + { + id: 'c67735cf-65df-451c-a956-20009200155d', + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + name: 'maxi plan sub arrears', + invoiceDisplayName: 'sub fee', + interval: 'monthly', + }, + }, + amountCents: '9999900', + description: null, + feeType: 'charge', + groupName: null, + invoiceDisplayName: null, + invoiceName: 'Advance recurring', + itemName: 'rec count', + units: 1, + preciseUnitAmount: 99999, + appliedTaxes: [ + { + id: '3d930b1c-e237-46e5-8c14-0b9d178a9f79', + taxRate: 20, + }, + ], + trueUpFee: null, + trueUpParentFee: null, + charge: { + id: '0fc08fb5-7cc1-43bd-a7d2-d3fac8835d0c', + payInAdvance: true, + invoiceDisplayName: 'Advance recurring', + billableMetric: { + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + aggregationType: 'unique_count_agg', + }, + chargeModel: 'standard', + minAmountCents: '0', + prorated: false, + }, + group: null, + eventsCount: '1', + amountDetails: { + graduatedRanges: null, + graduatedPercentageRanges: null, + flatUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + freeUnits: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + freeEvents: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + rate: null, + units: null, + }, + }, + ], + }, +] + +export const orderedSubscriptionWithFees = { + metadata: { + hasAnyFeeParsed: true, + }, + subscriptions: { + '0b9e37a0-9589-49d0-9da1-e39887d89ac2': { + feesInAdvance: [ + { + amountCents: '10000', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '03241fa4-63d6-4dfe-b038-8e6c7ba27e99', + taxRate: 20, + }, + ], + charge: null, + description: null, + eventsCount: null, + feeType: 'subscription', + group: null, + groupName: null, + id: '817ea1cc-f47b-4b48-806f-6a0ce03747a1', + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan sub arrears', + metadata: { + displayName: 'Monthly subscription fee - maxi plan sub arrears', + isSubscriptionFee: true, + }, + preciseUnitAmount: 100, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '9999900', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '7375835a-359d-4740-b8f7-a4d8c823ccb7', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '0fc08fb5-7cc1-43bd-a7d2-d3fac8835d0c', + invoiceDisplayName: 'Advance recurring', + minAmountCents: '0', + payInAdvance: true, + prorated: false, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: '9032acd1-a5c4-4c80-b500-94700d997d32', + invoiceDisplayName: null, + invoiceName: 'Advance recurring', + itemName: 'rec count', + metadata: { + displayName: 'Advance recurring', + isNormalFee: true, + }, + preciseUnitAmount: 99999, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '66700', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'ea35ee38-2d5f-4453-8a87-ba7a92269837', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '054ca896-1e1c-4190-ad42-eed7c24b9270', + invoiceDisplayName: 'rec count prorated advance', + minAmountCents: '0', + payInAdvance: true, + prorated: true, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: 'a54a6f27-ac59-45b7-bc0d-4a42415c1e47', + invoiceDisplayName: null, + invoiceName: 'rec count prorated advance', + itemName: 'rec count', + metadata: { + displayName: 'rec count prorated advance', + isNormalFee: true, + }, + preciseUnitAmount: 667, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + ], + feesInArrears: [ + { + amountCents: '1100000', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'cebee521-58f7-4dfd-919e-cd51e3ccd8fc', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'standard', + id: '34e6b422-b03e-4512-9778-93c1ad465c21', + invoiceDisplayName: 'metered arrears percentage minimum spending', + minAmountCents: '1100000', + payInAdvance: false, + prorated: false, + }, + description: null, + eventsCount: '0', + feeType: 'charge', + group: null, + groupName: null, + id: '72dbfa60-2cf4-43d7-9884-8107ada8d60a', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears percentage minimum spending', + isTrueUpFee: true, + }, + preciseUnitAmount: 11000, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: { + id: '061e4abe-9e92-4477-b5fb-987304f16735', + }, + units: 1, + }, + { + amountCents: '1000', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'e3e9793f-0f4c-4e6a-ae92-1f0f24658f38', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + invoiceDisplayName: '', + minAmountCents: '9999900', + payInAdvance: false, + prorated: false, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: 'f9aeb27c-4261-495b-86cb-c4ebea335ca5', + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + metadata: { + displayName: 'rec count', + isNormalFee: true, + }, + preciseUnitAmount: 10, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: { + id: 'cff1026b-baec-4fe2-a725-99532769865a', + }, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '9998900', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'baddf7d2-f84c-4424-a970-d0e9075eb0b3', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + invoiceDisplayName: '', + minAmountCents: '9999900', + payInAdvance: false, + prorated: false, + }, + description: null, + eventsCount: '0', + feeType: 'charge', + group: null, + groupName: null, + id: 'cff1026b-baec-4fe2-a725-99532769865a', + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + metadata: { + displayName: 'rec count', + isTrueUpFee: true, + }, + preciseUnitAmount: 99989, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: { + id: 'f9aeb27c-4261-495b-86cb-c4ebea335ca5', + }, + units: 1, + }, + { + amountCents: '200', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '1c1b3281-73e7-4113-a3de-650f462b0157', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'graduated', + id: 'bc29cfb6-998f-422d-858f-6107dd905530', + invoiceDisplayName: 'rec count prorated graduated', + minAmountCents: '0', + payInAdvance: false, + prorated: true, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: '1d19eec2-3ba6-49bc-8767-66f8e4b8b83a', + invoiceDisplayName: null, + invoiceName: 'rec count prorated graduated', + itemName: 'rec count', + metadata: { + displayName: 'rec count prorated graduated', + isNormalFee: true, + }, + preciseUnitAmount: 2, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '200', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: '1.0', + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '83e835ea-ae89-4a1e-aa49-3d48286262d9', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'volume', + id: '5575dc4f-f78c-4491-8ef0-9c778f1b4435', + invoiceDisplayName: 'rec count prorated volume', + minAmountCents: '0', + payInAdvance: false, + prorated: true, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: '2398dd5c-6558-45df-b97c-3e913f79c3ea', + invoiceDisplayName: null, + invoiceName: 'rec count prorated volume', + itemName: 'rec count', + metadata: { + displayName: 'rec count prorated volume', + isNormalFee: true, + }, + preciseUnitAmount: 2, + subscription: { + id: '0b9e37a0-9589-49d0-9da1-e39887d89ac2', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + ], + metadata: { + chargesFromDatetime: '2024-02-01T00:00:00Z', + chargesToDatetime: '2024-02-29T23:59:59Z', + differentBoundariesForSubscriptionAndCharges: true, + fromDatetime: '2024-03-01T00:00:00Z', + inAdvanceChargesFromDatetime: null, + inAdvanceChargesToDatetime: null, + subscriptionDisplayName: 'maxi plan sub arrears', + toDatetime: '2024-03-31T23:59:59Z', + }, + }, + '5cf07951-4296-46d1-9ca1-d4e87d6e6928': { + feesInAdvance: [ + { + amountCents: '10000', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'de9197a3-4919-40ca-85cf-4db578fd1961', + taxRate: 20, + }, + ], + charge: null, + description: null, + eventsCount: null, + feeType: 'subscription', + group: null, + groupName: null, + id: '626e9246-f986-4aa1-b586-3501f5b50dbc', + invoiceDisplayName: null, + invoiceName: 'sub fee', + itemName: 'maxi plan sub arrears', + metadata: { + displayName: 'Monthly subscription fee - maxi plan sub arrears', + isSubscriptionFee: true, + }, + preciseUnitAmount: 100, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '9999900', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '3d930b1c-e237-46e5-8c14-0b9d178a9f79', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '0fc08fb5-7cc1-43bd-a7d2-d3fac8835d0c', + invoiceDisplayName: 'Advance recurring', + minAmountCents: '0', + payInAdvance: true, + prorated: false, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: 'c67735cf-65df-451c-a956-20009200155d', + invoiceDisplayName: null, + invoiceName: 'Advance recurring', + itemName: 'rec count', + metadata: { + displayName: 'Advance recurring', + isNormalFee: true, + }, + preciseUnitAmount: 99999, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '66700', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'ec8d1e3c-6cee-40f4-8e4a-70850ceecded', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '054ca896-1e1c-4190-ad42-eed7c24b9270', + invoiceDisplayName: 'rec count prorated advance', + minAmountCents: '0', + payInAdvance: true, + prorated: true, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: '86ee400c-a0c5-4e7b-a6c4-0915a7296fcd', + invoiceDisplayName: null, + invoiceName: 'rec count prorated advance', + itemName: 'rec count', + metadata: { + displayName: 'rec count prorated advance', + isNormalFee: true, + }, + preciseUnitAmount: 667, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + ], + feesInArrears: [ + { + amountCents: '1100000', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'ee18bd57-db30-4ea9-9640-24b1ca7ffd9a', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'count_agg', + id: 'efd12be5-f4fd-4f22-8c81-9fb0cd98b0a8', + name: 'Count BM', + }, + chargeModel: 'standard', + id: '34e6b422-b03e-4512-9778-93c1ad465c21', + invoiceDisplayName: 'metered arrears percentage minimum spending', + minAmountCents: '1100000', + payInAdvance: false, + prorated: false, + }, + description: null, + eventsCount: '0', + feeType: 'charge', + group: null, + groupName: null, + id: '599299c4-7519-44f6-9a48-26814677e2e0', + invoiceDisplayName: null, + invoiceName: 'metered arrears percentage minimum spending', + itemName: 'Count BM', + metadata: { + displayName: 'metered arrears percentage minimum spending', + isTrueUpFee: true, + }, + preciseUnitAmount: 11000, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: { + id: '1acab4b6-1f30-450f-b87a-02dbf2ce31ec', + }, + units: 1, + }, + { + amountCents: '1000', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'ee77a4ee-4013-4d74-8830-8cb2fb68fabb', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + invoiceDisplayName: '', + minAmountCents: '9999900', + payInAdvance: false, + prorated: false, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: 'cc82649b-37b5-4be2-9068-43665288a1d4', + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + metadata: { + displayName: 'rec count', + isNormalFee: true, + }, + preciseUnitAmount: 10, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: { + id: '161c7a55-a56e-4f38-8009-ae6a3bd29edc', + }, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '9998900', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '8d47e1e3-8f75-446d-8c14-f8ba3b58c095', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'standard', + id: '8b6a6273-6f61-4616-946d-8604edf49f4e', + invoiceDisplayName: '', + minAmountCents: '9999900', + payInAdvance: false, + prorated: false, + }, + description: null, + eventsCount: '0', + feeType: 'charge', + group: null, + groupName: null, + id: '161c7a55-a56e-4f38-8009-ae6a3bd29edc', + invoiceDisplayName: null, + invoiceName: 'rec count', + itemName: 'rec count', + metadata: { + displayName: 'rec count', + isTrueUpFee: true, + }, + preciseUnitAmount: 99989, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: { + id: 'cc82649b-37b5-4be2-9068-43665288a1d4', + }, + units: 1, + }, + { + amountCents: '200', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: null, + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: null, + perUnitTotalAmount: null, + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: 'a0c2fc7c-c091-465a-8133-83c292557770', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'graduated', + id: 'bc29cfb6-998f-422d-858f-6107dd905530', + invoiceDisplayName: 'rec count prorated graduated', + minAmountCents: '0', + payInAdvance: false, + prorated: true, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: 'c94363c5-6f45-490e-8b9f-7c4c41cd725e', + invoiceDisplayName: null, + invoiceName: 'rec count prorated graduated', + itemName: 'rec count', + metadata: { + displayName: 'rec count prorated graduated', + isNormalFee: true, + }, + preciseUnitAmount: 2, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + { + amountCents: '200', + amountDetails: { + fixedFeeTotalAmount: null, + fixedFeeUnitAmount: null, + flatUnitAmount: '1.0', + freeEvents: null, + freeUnits: null, + graduatedPercentageRanges: null, + graduatedRanges: null, + minMaxAdjustmentTotalAmount: null, + paidEvents: null, + paidUnits: null, + perPackageSize: null, + perPackageUnitAmount: null, + perUnitAmount: '1.0', + perUnitTotalAmount: '1.0', + rate: null, + units: null, + }, + appliedTaxes: [ + { + id: '52a03e29-7a8c-445d-a143-579f38a84bf3', + taxRate: 20, + }, + ], + charge: { + billableMetric: { + aggregationType: 'unique_count_agg', + id: 'aecf4a46-c08c-48a0-88c1-dc1c894f9bf2', + name: 'rec count', + }, + chargeModel: 'volume', + id: '5575dc4f-f78c-4491-8ef0-9c778f1b4435', + invoiceDisplayName: 'rec count prorated volume', + minAmountCents: '0', + payInAdvance: false, + prorated: true, + }, + description: null, + eventsCount: '1', + feeType: 'charge', + group: null, + groupName: null, + id: '609a8c7a-756d-4468-a70b-a270183b22b7', + invoiceDisplayName: null, + invoiceName: 'rec count prorated volume', + itemName: 'rec count', + metadata: { + displayName: 'rec count prorated volume', + isNormalFee: true, + }, + preciseUnitAmount: 2, + subscription: { + id: '5cf07951-4296-46d1-9ca1-d4e87d6e6928', + name: '', + plan: { + id: 'ee3f1bf6-1be1-4def-b5b9-2b0bffba15ce', + interval: 'monthly', + invoiceDisplayName: 'sub fee', + name: 'maxi plan sub arrears', + }, + }, + trueUpFee: null, + trueUpParentFee: null, + units: 1, + }, + ], + metadata: { + chargesFromDatetime: '2024-02-11T00:00:00Z', + chargesToDatetime: '2024-03-10T23:59:59Z', + differentBoundariesForSubscriptionAndCharges: true, + fromDatetime: '2024-03-11T00:00:00Z', + inAdvanceChargesFromDatetime: null, + inAdvanceChargesToDatetime: null, + subscriptionDisplayName: 'maxi plan sub arrears', + toDatetime: '2024-04-10T23:59:59Z', + }, + }, + }, +} diff --git a/src/core/formats/__tests__/formatInvoiceItemsMap.test.ts b/src/core/formats/__tests__/formatInvoiceItemsMap.test.ts new file mode 100644 index 000000000..d1d27997b --- /dev/null +++ b/src/core/formats/__tests__/formatInvoiceItemsMap.test.ts @@ -0,0 +1,98 @@ +import { InvoiceSubscription } from '~/generated/graphql' + +import { + chargeZeroAmount, + noFees, + noFeesResult, + oneSubscription, + oneSubscriptionResult, + orderedSubscriptionWithFees, + subZeroAmount, + twoSubscriptions, + twoSubscriptionsResult, + unorderedSubscriptionWithFees, +} from './fixture' + +import { + getSubscriptionFeeDisplayName, + groupAndFormatFees, + TExtendedRemainingFee, +} from '../formatInvoiceItemsMap' + +describe('formatInvoiceItemsMap', () => { + describe('getSubscriptionFeeDisplayName', () => { + it('should return the plan name formated by default', () => { + const fee = { + invoiceDisplayName: null, + subscription: { + plan: { + name: 'Plan name', + interval: 'monthly', + }, + }, + } + + const result = getSubscriptionFeeDisplayName(fee as TExtendedRemainingFee) + + expect(result).toEqual('Monthly subscription fee - Plan name') + }) + + it('should return the invoiceDisplayName if it exists', () => { + const fee = { + invoiceDisplayName: 'Custom invoice display name', + subscription: { + plan: { + interval: 'monthly', + }, + }, + } + + const result = getSubscriptionFeeDisplayName(fee as TExtendedRemainingFee) + + expect(result).toEqual('Custom invoice display name') + }) + }) + + describe('groupAndFormatFees', () => { + it('should return default values if there are no data', () => { + const result = groupAndFormatFees([]) + + expect(result).toEqual({ + subscriptions: {}, + metadata: { hasAnyFeeParsed: false }, + }) + }) + it('should return default values if there are no fees', () => { + const result = groupAndFormatFees(noFees as unknown as InvoiceSubscription[]) + + expect(result).toEqual(noFeesResult) + }) + it('should return default values if there are only sub fee with 0 amountCents', () => { + const result = groupAndFormatFees(subZeroAmount as unknown as InvoiceSubscription[]) + + expect(result).toEqual(noFeesResult) + }) + it('should return default values if there are only sub fee with 0 amountCents and 0 units', () => { + const result = groupAndFormatFees(chargeZeroAmount as unknown as InvoiceSubscription[]) + + expect(result).toEqual(noFeesResult) + }) + it('should return the correct values if there are 1 subscription', () => { + const result = groupAndFormatFees(oneSubscription as unknown as InvoiceSubscription[]) + + expect(result).toEqual(oneSubscriptionResult) + }) + it('should return the correct values if there are 2 subscription', () => { + const result = groupAndFormatFees(twoSubscriptions as unknown as InvoiceSubscription[]) + + expect(result).toEqual(twoSubscriptionsResult) + }) + it('should return the correct order for a given subscription', () => { + const result = groupAndFormatFees( + unorderedSubscriptionWithFees as unknown as InvoiceSubscription[], + ) + + expect(result).toEqual(orderedSubscriptionWithFees) + }) + }) +}) diff --git a/src/core/formats/formatInvoiceItemsMap.ts b/src/core/formats/formatInvoiceItemsMap.ts index be2d9e005..0149bb67a 100644 --- a/src/core/formats/formatInvoiceItemsMap.ts +++ b/src/core/formats/formatInvoiceItemsMap.ts @@ -1,144 +1,243 @@ -import _groupBy from 'lodash/groupBy' +import { gql } from '@apollo/client' import { Fee, FeeTypesEnum, InvoiceSubscription } from '~/generated/graphql' -export type ExtendedRemainingFee = Fee & { - displayName: string - isGroupChildFee?: boolean - isTrueUpFee?: boolean - isNormalFee?: boolean +gql` + fragment InvoiceSubscriptionFormating on InvoiceSubscription { + fromDatetime + toDatetime + chargesFromDatetime + chargesToDatetime + inAdvanceChargesFromDatetime + inAdvanceChargesToDatetime + fees { + id + amountCents + invoiceName + invoiceDisplayName + groupName + units + charge { + id + payInAdvance + minAmountCents + billableMetric { + id + name + } + } + subscription { + id + plan { + id + interval + } + } + } + subscription { + id + name + plan { + id + name + invoiceDisplayName + } + } + } +` +export type TExtendedRemainingFee = Fee & { + metadata: { + displayName: string + isSubscriptionFee?: boolean + isGroupChildFee?: boolean + isTrueUpFee?: boolean + isNormalFee?: boolean + } } - -interface BaseFormattedInvoiceSubscription { - invoiceSubscription: InvoiceSubscription - currentSubscription: InvoiceSubscription['subscription'] - invoiceDisplayName: string - subscriptionFees: InvoiceSubscription['subscription']['fees'] - feesInArrears: InvoiceSubscription['subscription']['fees'] - feesInAdvance: InvoiceSubscription['subscription']['fees'] +type TSubscriptionDataForDisplay = { + [invoiceSubscriptionId: string]: { + feesInArrears: TExtendedRemainingFee[] + feesInAdvance: TExtendedRemainingFee[] + metadata: { + differentBoundariesForSubscriptionAndCharges: boolean + subscriptionDisplayName: string + fromDatetime: string + toDatetime: string + chargesFromDatetime: string + chargesToDatetime: string + inAdvanceChargesFromDatetime: string + inAdvanceChargesToDatetime: string + } + } } +type TFormatedInvoiceSubscriptionDataForDisplay = { + subscriptions: TSubscriptionDataForDisplay + metadata: { + hasAnyFeeParsed: boolean + } +} + +export const getSubscriptionFeeDisplayName = (fee: TExtendedRemainingFee) => { + if (!!fee.invoiceDisplayName) { + return fee.invoiceDisplayName + } + + const plan = fee.subscription?.plan + const capitalizedPlanInterval = `${plan?.interval + ?.charAt(0) + ?.toUpperCase()}${plan?.interval?.slice(1)}` -interface FormattedInvoiceSubscription - extends Omit { - feesInArrears: ExtendedRemainingFee[] - feesInAdvance: ExtendedRemainingFee[] + return `${capitalizedPlanInterval} subscription fee - ${plan?.name}` } -const formatInvoiceItemsMap = (data: InvoiceSubscription[]) => { - return data.map((invoiceSubscription) => { - const currentSubscription = invoiceSubscription.subscription - - let formattedData: FormattedInvoiceSubscription = { - invoiceSubscription, - currentSubscription, - invoiceDisplayName: !!currentSubscription - ? currentSubscription?.name || currentSubscription?.plan?.name - : '', - subscriptionFees: [], - feesInArrears: [], - feesInAdvance: [], - } +export const groupAndFormatFees = ( + invoiceSubscription: InvoiceSubscription[] | null | undefined, +): TFormatedInvoiceSubscriptionDataForDisplay => { + let hasAnyFeeParsed = false + + if (!invoiceSubscription?.length) return { subscriptions: {}, metadata: { hasAnyFeeParsed } } + + const feesGroupedBySubscription = invoiceSubscription?.reduce( + (acc, invoiceSub) => { + const subscriptionId = invoiceSub?.subscription?.id + + if (!subscriptionId) return acc + + const differentBoundariesForSubscriptionAndCharges: boolean = + invoiceSub.fromDatetime !== invoiceSub.chargesFromDatetime && + invoiceSub.toDatetime !== invoiceSub.chargesToDatetime + + if (!acc[subscriptionId]) { + acc[subscriptionId] = { + feesInArrears: [], + feesInAdvance: [], + metadata: { + differentBoundariesForSubscriptionAndCharges, + subscriptionDisplayName: + invoiceSub.subscription.name || invoiceSub.subscription.plan.name, + fromDatetime: invoiceSub?.fromDatetime, + toDatetime: invoiceSub?.toDatetime, + chargesFromDatetime: invoiceSub?.chargesFromDatetime, + chargesToDatetime: invoiceSub?.chargesToDatetime, + inAdvanceChargesFromDatetime: invoiceSub?.inAdvanceChargesFromDatetime, + inAdvanceChargesToDatetime: invoiceSub?.inAdvanceChargesToDatetime, + }, + } + } + + if (!invoiceSub?.fees?.length) return acc + + // Group fees advance / arrear + for (let i = 0; i < invoiceSub?.fees?.length; i++) { + const currentFee = invoiceSub?.fees[i] as TExtendedRemainingFee + + // Prevent zero amount fees from being displayed + if ( + (currentFee.feeType === FeeTypesEnum.Subscription && + Number(currentFee.amountCents) === 0) || + (currentFee.units === 0 && Number(currentFee.amountCents) === 0) + ) + continue - if (!invoiceSubscription?.fees?.length) return formattedData - - // Build up data - for (let i = 0; i < invoiceSubscription?.fees?.length; i++) { - const currentFee = invoiceSubscription?.fees[i] - - // Prevent zero amount fees from being displayed - if (currentFee.amountCents === 0) continue - - // Split fees into subscription fees and remaining fees depending on fee type - if (currentFee.feeType === FeeTypesEnum.Subscription) { - formattedData?.subscriptionFees?.push(currentFee) - } else if (!currentFee?.charge?.payInAdvance) { - // Charge paid in arrears - // @ts-ignore - formattedData?.feesInArrears?.push(currentFee) - } else { - // Charge paid in advance - // @ts-ignore - formattedData?.feesInAdvance?.push(currentFee) + // Flag that at least one fee has been parsed + !hasAnyFeeParsed && (hasAnyFeeParsed = true) + const isSubscriptionFeeInAdvance = + currentFee.feeType === FeeTypesEnum.Subscription && + differentBoundariesForSubscriptionAndCharges + + if (currentFee?.charge?.payInAdvance || isSubscriptionFeeInAdvance) { + acc[subscriptionId]?.feesInAdvance?.push(currentFee) + } else { + acc[subscriptionId]?.feesInArrears?.push(currentFee) + } } - } - // Format fees - if (formattedData?.feesInArrears?.length) { - formattedData.feesInArrears = _deepFormatFees( - formattedData.feesInArrears as unknown as BaseFormattedInvoiceSubscription['feesInArrears'], + return acc + }, + {}, + ) + + // Format fees + Object.keys(feesGroupedBySubscription).forEach((subscriptionId) => { + const subscription = feesGroupedBySubscription[subscriptionId] + + if (subscription?.feesInArrears?.length) { + feesGroupedBySubscription[subscriptionId].feesInArrears = _newDeepFormatFees( + subscription.feesInArrears, ) } - if (formattedData?.feesInAdvance?.length) { - formattedData.feesInAdvance = _deepFormatFees( - formattedData.feesInAdvance as unknown as BaseFormattedInvoiceSubscription['feesInAdvance'], + if (subscription?.feesInAdvance?.length) { + feesGroupedBySubscription[subscriptionId].feesInAdvance = _newDeepFormatFees( + subscription.feesInAdvance, ) } - return formattedData }) + + return { + subscriptions: feesGroupedBySubscription, + metadata: { + hasAnyFeeParsed, + }, + } } -const _deepFormatFees = ( - feesToFormat: - | BaseFormattedInvoiceSubscription['feesInArrears'] - | BaseFormattedInvoiceSubscription['feesInAdvance'], -) => { - return Object.values(_groupBy(feesToFormat, (fee) => fee?.charge?.id)) - .map((fees) => { - const feesData: ExtendedRemainingFee[] = [] - - // Mark fees depending on their type and add a display name - for (let i = 0; i < fees.length; i++) { - const fee = fees[i] - - if (!!fee.group?.id) { - feesData.push({ - ...fee, - isGroupChildFee: true, - displayName: `${`${fee.invoiceName || fee.charge?.billableMetric?.name} • `}${ - fee.groupName - ? fee.groupName - : `${!!fee.group?.key ? `${fee.group?.key} • ` : ''}${fee.group.value}` - }`, - }) - } else if (!!fee?.trueUpParentFee?.id) { - feesData.push({ - ...fee, - isTrueUpFee: true, - displayName: fee.groupName || fee.invoiceName || fee.charge?.billableMetric?.name || '', - }) - } else { - feesData.push({ - ...fee, - isNormalFee: true, - displayName: - fee.invoiceDisplayName || fee.invoiceName || fee.charge?.billableMetric?.name || '', - }) - } - } +const _newDeepFormatFees = (feesToFormat: TExtendedRemainingFee[]): TExtendedRemainingFee[] => { + const feesData: TExtendedRemainingFee[] = [] - // return sorted feesData - // - Normal fees - // - Group child fees - // - True-up fees - return feesData.sort((a, b) => { - if (!!a.isNormalFee && !b.isNormalFee) { - return -1 - } else if (!a.isNormalFee && !!b.isNormalFee) { - return 1 - } else if (!!a.isGroupChildFee && !b.isGroupChildFee) { - return -1 - } else if (!a.isGroupChildFee && !!b.isGroupChildFee) { - return 1 - } else if (!!a.isTrueUpFee && !b.isTrueUpFee) { - return -1 - } else if (!a.isTrueUpFee && !!b.isTrueUpFee) { - return 1 - } + // Mark fees depending on their type and add a display name + for (let i = 0; i < feesToFormat.length; i++) { + const fee = feesToFormat[i] - return 0 + if (fee.feeType === FeeTypesEnum.Subscription) { + feesData.push({ + ...fee, + metadata: { + isSubscriptionFee: true, + displayName: getSubscriptionFeeDisplayName(fee), + }, + }) + } else if (!!fee.group?.id) { + feesData.push({ + ...fee, + metadata: { + isGroupChildFee: true, + displayName: `${`${fee.invoiceName || fee.charge?.billableMetric?.name} • `}${ + fee.groupName + ? fee.groupName + : `${!!fee.group?.key ? `${fee.group?.key} • ` : ''}${fee.group.value}` + }`, + }, + }) + } else if (!!fee?.trueUpParentFee?.id) { + feesData.push({ + ...fee, + metadata: { + isTrueUpFee: true, + displayName: fee.groupName || fee.invoiceName || fee.charge?.billableMetric?.name || '', + }, + }) + } else { + feesData.push({ + ...fee, + metadata: { + isNormalFee: true, + displayName: + fee.invoiceDisplayName || fee.invoiceName || fee.charge?.billableMetric?.name || '', + }, }) - }) - .flat() + } + } + + return feesData.sort((a, b) => { + if (!!a?.metadata?.isSubscriptionFee && !b?.metadata?.isSubscriptionFee) { + return -1 + } else if (!a?.metadata?.isSubscriptionFee && !!b?.metadata?.isSubscriptionFee) { + return 1 + } else if (a?.metadata?.displayName.toLowerCase() < b?.metadata?.displayName.toLowerCase()) { + return -1 + } else if (a?.metadata?.displayName.toLowerCase() > b?.metadata?.displayName.toLowerCase()) { + return 1 + } + return 0 + }) } - -export default formatInvoiceItemsMap diff --git a/src/core/router/SettingRoutes.tsx b/src/core/router/SettingRoutes.tsx index f8d33b463..f29eda282 100644 --- a/src/core/router/SettingRoutes.tsx +++ b/src/core/router/SettingRoutes.tsx @@ -21,16 +21,40 @@ const Members = lazyLoad(() => import(/* webpackChunkName: 'members' */ '~/pages const Integrations = lazyLoad( () => import(/* webpackChunkName: 'integrations' */ '~/pages/settings/Integrations'), ) -const AdyenIntegration = lazyLoad( - () => import(/* webpackChunkName: 'adyen-integration' */ '~/pages/settings/AdyenIntegration'), +const AdyenIntegrations = lazyLoad( + () => import(/* webpackChunkName: 'adyen-integrations' */ '~/pages/settings/AdyenIntegrations'), ) -const StripeIntegration = lazyLoad( - () => import(/* webpackChunkName: 'stripe-integration' */ '~/pages/settings/StripeIntegration'), +const AdyenIntegrationDetails = lazyLoad( + () => + import( + /* webpackChunkName: 'adyen-integration-details' */ '~/pages/settings/AdyenIntegrationDetails' + ), +) +const StripeIntegrations = lazyLoad( + () => import(/* webpackChunkName: 'stripe-integrations' */ '~/pages/settings/StripeIntegrations'), +) +const StripeIntegrationDetails = lazyLoad( + () => + import( + /* webpackChunkName: 'stripe-integration-details' */ '~/pages/settings/StripeIntegrationDetails' + ), +) +const GocardlessIntegrationOauthCallback = lazyLoad( + () => + import( + /* webpackChunkName: 'gocardless-integration-oauth-callback' */ '~/pages/settings/GocardlessIntegrationOauthCallback' + ), +) +const GocardlessIntegrations = lazyLoad( + () => + import( + /* webpackChunkName: 'gocardless-integrations' */ '~/pages/settings/GocardlessIntegrations' + ), ) -const GocardlessIntegration = lazyLoad( +const GocardlessIntegrationDetails = lazyLoad( () => import( - /* webpackChunkName: 'gocardless-integration' */ '~/pages/settings/GocardlessIntegration' + /* webpackChunkName: 'gocardless-integration-details' */ '~/pages/settings/GocardlessIntegrationDetails' ), ) const TaxManagementIntegration = lazyLoad( @@ -54,8 +78,12 @@ export const TAXES_SETTINGS_ROUTE = `${SETTINGS_ROUTE}/taxes` export const ORGANIZATION_INFORMATIONS_ROUTE = `${SETTINGS_ROUTE}/organization-informations` export const INTEGRATIONS_ROUTE = `${SETTINGS_ROUTE}/integrations` export const ADYEN_INTEGRATION_ROUTE = `${SETTINGS_ROUTE}/integrations/adyen` +export const ADYEN_INTEGRATION_DETAILS_ROUTE = `${SETTINGS_ROUTE}/integrations/adyen/:integrationId` export const STRIPE_INTEGRATION_ROUTE = `${SETTINGS_ROUTE}/integrations/stripe` +export const STRIPE_INTEGRATION_DETAILS_ROUTE = `${SETTINGS_ROUTE}/integrations/stripe/:integrationId` export const GOCARDLESS_INTEGRATION_ROUTE = `${SETTINGS_ROUTE}/integrations/gocardless` +export const GOCARDLESS_INTEGRATION_OAUTH_CALLBACK_ROUTE = `${SETTINGS_ROUTE}/integrations/gocardless/callback` +export const GOCARDLESS_INTEGRATION_DETAILS_ROUTE = `${SETTINGS_ROUTE}/integrations/gocardless/:integrationId` export const TAX_MANAGEMENT_INTEGRATION_ROUTE = `${SETTINGS_ROUTE}/integrations/lago-tax-management` export const MEMBERS_ROUTE = `${SETTINGS_ROUTE}/members` export const EMAILS_SETTINGS_ROUTE = `${SETTINGS_ROUTE}/emails` @@ -98,20 +126,40 @@ export const settingRoutes: CustomRouteObject[] = [ }, ], }, + { + path: ADYEN_INTEGRATION_DETAILS_ROUTE, + private: true, + element: , + }, { path: ADYEN_INTEGRATION_ROUTE, private: true, - element: , + element: , }, { path: STRIPE_INTEGRATION_ROUTE, private: true, - element: , + element: , + }, + { + path: STRIPE_INTEGRATION_DETAILS_ROUTE, + private: true, + element: , + }, + { + path: GOCARDLESS_INTEGRATION_OAUTH_CALLBACK_ROUTE, + private: true, + element: , }, { path: GOCARDLESS_INTEGRATION_ROUTE, private: true, - element: , + element: , + }, + { + path: GOCARDLESS_INTEGRATION_DETAILS_ROUTE, + private: true, + element: , }, { path: TAX_MANAGEMENT_INTEGRATION_ROUTE, diff --git a/src/formValidation/metadataSchema.ts b/src/formValidation/metadataSchema.ts index 0c4a0f4e3..f9d2a95d6 100644 --- a/src/formValidation/metadataSchema.ts +++ b/src/formValidation/metadataSchema.ts @@ -17,7 +17,7 @@ export const metadataSchema = ({ valueMaxLength = METADATA_VALUE_MAX_LENGTH_DEFA return false } - if (arguments[1].from[1]?.value?.metadata.length > 1) { + if (arguments[1].from[1]?.value?.metadata?.length > 1) { const keysList = arguments[1].from[1]?.value?.metadata?.map( (m: { key: string }) => m.key, ) diff --git a/src/generated/graphql.tsx b/src/generated/graphql.tsx index 6c36afe7c..2c4b99963 100644 --- a/src/generated/graphql.tsx +++ b/src/generated/graphql.tsx @@ -40,9 +40,11 @@ export type AddAdyenPaymentProviderInput = { apiKey: Scalars['String']['input']; /** A unique identifier for the client performing the mutation. */ clientMutationId?: InputMaybe; + code: Scalars['String']['input']; hmacKey?: InputMaybe; livePrefix?: InputMaybe; merchantAccount: Scalars['String']['input']; + name: Scalars['String']['input']; successRedirectUrl?: InputMaybe; }; @@ -51,6 +53,8 @@ export type AddGocardlessPaymentProviderInput = { accessCode?: InputMaybe; /** A unique identifier for the client performing the mutation. */ clientMutationId?: InputMaybe; + code: Scalars['String']['input']; + name: Scalars['String']['input']; successRedirectUrl?: InputMaybe; }; @@ -83,18 +87,21 @@ export type AddOnCollection = { export type AddStripePaymentProviderInput = { /** A unique identifier for the client performing the mutation. */ clientMutationId?: InputMaybe; - createCustomers?: InputMaybe; + code: Scalars['String']['input']; + name: Scalars['String']['input']; secretKey?: InputMaybe; successRedirectUrl?: InputMaybe; }; export type AdyenProvider = { __typename?: 'AdyenProvider'; - apiKey: Scalars['String']['output']; + apiKey?: Maybe; + code: Scalars['String']['output']; hmacKey?: Maybe; id: Scalars['ID']['output']; livePrefix?: Maybe; merchantAccount: Scalars['String']['output']; + name: Scalars['String']['output']; successRedirectUrl?: Maybe; }; @@ -817,6 +824,16 @@ export type CreateAddOnInput = { taxCodes?: InputMaybe>; }; +/** Create Adjusted Fee Input */ +export type CreateAdjustedFeeInput = { + /** A unique identifier for the client performing the mutation. */ + clientMutationId?: InputMaybe; + feeId: Scalars['ID']['input']; + invoiceDisplayName?: InputMaybe; + unitAmountCents?: InputMaybe; + units: Scalars['Float']['input']; +}; + /** Autogenerated input type of CreateAppliedCoupon */ export type CreateAppliedCouponInput = { amountCents?: InputMaybe; @@ -896,6 +913,7 @@ export type CreateCustomerInput = { name: Scalars['String']['input']; netPaymentTerm?: InputMaybe; paymentProvider?: InputMaybe; + paymentProviderCode?: InputMaybe; phone?: InputMaybe; providerCustomer?: InputMaybe; state?: InputMaybe; @@ -1433,6 +1451,7 @@ export type Customer = { name?: Maybe; netPaymentTerm?: Maybe; paymentProvider?: Maybe; + paymentProviderCode?: Maybe; phone?: Maybe; providerCustomer?: Maybe; sequentialId: Scalars['String']['output']; @@ -1513,6 +1532,21 @@ export type DestroyAddOnPayload = { id?: Maybe; }; +/** Autogenerated input type of DestroyAdjustedFee */ +export type DestroyAdjustedFeeInput = { + /** A unique identifier for the client performing the mutation. */ + clientMutationId?: InputMaybe; + id: Scalars['ID']['input']; +}; + +/** Autogenerated return type of DestroyAdjustedFee */ +export type DestroyAdjustedFeePayload = { + __typename?: 'DestroyAdjustedFeePayload'; + /** A unique identifier for the client performing the mutation. */ + clientMutationId?: Maybe; + id?: Maybe; +}; + /** Autogenerated input type of DestroyBillableMetric */ export type DestroyBillableMetricInput = { /** A unique identifier for the client performing the mutation. */ @@ -1684,6 +1718,7 @@ export type Fee = InvoiceItem & { __typename?: 'Fee'; amountCents: Scalars['BigInt']['output']; amountCurrency: CurrencyEnum; + amountDetails?: Maybe; appliedTaxes?: Maybe>; charge?: Maybe; creditableAmountCents: Scalars['BigInt']['output']; @@ -1708,6 +1743,48 @@ export type Fee = InvoiceItem & { units: Scalars['Float']['output']; }; +export type FeeAmountDetails = { + __typename?: 'FeeAmountDetails'; + fixedFeeTotalAmount?: Maybe; + fixedFeeUnitAmount?: Maybe; + flatUnitAmount?: Maybe; + freeEvents?: Maybe; + freeUnits?: Maybe; + graduatedPercentageRanges?: Maybe>; + graduatedRanges?: Maybe>; + minMaxAdjustmentTotalAmount?: Maybe; + paidEvents?: Maybe; + paidUnits?: Maybe; + perPackageSize?: Maybe; + perPackageUnitAmount?: Maybe; + perUnitAmount?: Maybe; + perUnitTotalAmount?: Maybe; + rate?: Maybe; + units?: Maybe; +}; + +export type FeeAmountDetailsGraduatedPercentageRange = { + __typename?: 'FeeAmountDetailsGraduatedPercentageRange'; + flatUnitAmount?: Maybe; + fromValue?: Maybe; + perUnitTotalAmount?: Maybe; + rate?: Maybe; + toValue?: Maybe; + totalWithFlatAmount?: Maybe; + units?: Maybe; +}; + +export type FeeAmountDetailsGraduatedRange = { + __typename?: 'FeeAmountDetailsGraduatedRange'; + flatUnitAmount?: Maybe; + fromValue?: Maybe; + perUnitAmount?: Maybe; + perUnitTotalAmount?: Maybe; + toValue?: Maybe; + totalWithFlatAmount?: Maybe; + units?: Maybe; +}; + export type FeeAppliedTax = AppliedTax & { __typename?: 'FeeAppliedTax'; amountCents: Scalars['BigInt']['output']; @@ -1737,6 +1814,7 @@ export type FeeInput = { export enum FeeTypesEnum { AddOn = 'add_on', Charge = 'charge', + Commitment = 'commitment', Credit = 'credit', Subscription = 'subscription' } @@ -1780,8 +1858,10 @@ export type GenerateCustomerPortalUrlPayload = { export type GocardlessProvider = { __typename?: 'GocardlessProvider'; + code: Scalars['String']['output']; hasAccessToken: Scalars['Boolean']['output']; id: Scalars['ID']['output']; + name: Scalars['String']['output']; successRedirectUrl?: Maybe; webhookSecret?: Maybe; }; @@ -2116,6 +2196,8 @@ export type Mutation = { addStripePaymentProvider?: Maybe; /** Creates a new add-on */ createAddOn?: Maybe; + /** Creates Adjusted Fee */ + createAdjustedFee?: Maybe; /** Assigns a Coupon to a Customer */ createAppliedCoupon?: Maybe; /** Creates a new Billable metric */ @@ -2146,6 +2228,8 @@ export type Mutation = { createWebhookEndpoint?: Maybe; /** Deletes an add-on */ destroyAddOn?: Maybe; + /** Deletes an adjusted fee */ + destroyAdjustedFee?: Maybe; /** Deletes a Billable metric */ destroyBillableMetric?: Maybe; /** Deletes a coupon */ @@ -2260,6 +2344,11 @@ export type MutationCreateAddOnArgs = { }; +export type MutationCreateAdjustedFeeArgs = { + input: CreateAdjustedFeeInput; +}; + + export type MutationCreateAppliedCouponArgs = { input: CreateAppliedCouponInput; }; @@ -2335,6 +2424,11 @@ export type MutationDestroyAddOnArgs = { }; +export type MutationDestroyAdjustedFeeArgs = { + input: DestroyAdjustedFeeInput; +}; + + export type MutationDestroyBillableMetricArgs = { input: DestroyBillableMetricInput; }; @@ -2554,7 +2648,7 @@ export type Organization = { __typename?: 'Organization'; addressLine1?: Maybe; addressLine2?: Maybe; - adyenPaymentProvider?: Maybe; + adyenPaymentProviders?: Maybe>; apiKey: Scalars['String']['output']; billingConfiguration?: Maybe; city?: Maybe; @@ -2566,7 +2660,7 @@ export type Organization = { email?: Maybe; emailSettings?: Maybe>; euTaxManagement: Scalars['Boolean']['output']; - gocardlessPaymentProvider?: Maybe; + gocardlessPaymentProviders?: Maybe>; id: Scalars['ID']['output']; legalName?: Maybe; legalNumber?: Maybe; @@ -2574,7 +2668,7 @@ export type Organization = { name: Scalars['String']['output']; netPaymentTerm: Scalars['Int']['output']; state?: Maybe; - stripePaymentProvider?: Maybe; + stripePaymentProviders?: Maybe>; taxIdentificationNumber?: Maybe; /** Query taxes of an organization */ taxes?: Maybe>; @@ -2611,6 +2705,14 @@ export type OrganizationBillingConfigurationInput = { invoiceGracePeriod?: InputMaybe; }; +export type PaymentProvider = AdyenProvider | GocardlessProvider | StripeProvider; + +export type PaymentProviderCollection = { + __typename?: 'PaymentProviderCollection'; + collection: Array; + metadata: CollectionMetadata; +}; + export type Plan = { __typename?: 'Plan'; activeSubscriptionsCount: Scalars['Int']['output']; @@ -2783,6 +2885,10 @@ export type Query = { organization?: Maybe; /** Query a password reset by token */ passwordReset: ResetPassword; + /** Query a single payment provider */ + paymentProvider?: Maybe; + /** Query organization's payment providers */ + paymentProviders?: Maybe; /** Query a single plan of an organization */ plan?: Maybe; /** Query plans of an organization */ @@ -2979,6 +3085,19 @@ export type QueryPasswordResetArgs = { }; +export type QueryPaymentProviderArgs = { + code?: InputMaybe; + id?: InputMaybe; +}; + + +export type QueryPaymentProvidersArgs = { + limit?: InputMaybe; + page?: InputMaybe; + type?: InputMaybe; +}; + + export type QueryPlanArgs = { id: Scalars['ID']['input']; }; @@ -3173,9 +3292,10 @@ export enum StatusTypeEnum { export type StripeProvider = { __typename?: 'StripeProvider'; - createCustomers: Scalars['Boolean']['output']; + code: Scalars['String']['output']; id: Scalars['ID']['output']; - secretKey: Scalars['String']['output']; + name: Scalars['String']['output']; + secretKey?: Maybe; successRedirectUrl?: Maybe; }; @@ -3574,10 +3694,13 @@ export type UpdateAddOnInput = { taxCodes?: InputMaybe>; }; -/** Autogenerated input type of UpdateAdyenPaymentProvider */ +/** Update input arguments */ export type UpdateAdyenPaymentProviderInput = { /** A unique identifier for the client performing the mutation. */ clientMutationId?: InputMaybe; + code?: InputMaybe; + id: Scalars['ID']['input']; + name?: InputMaybe; successRedirectUrl?: InputMaybe; }; @@ -3646,6 +3769,7 @@ export type UpdateCustomerInput = { name: Scalars['String']['input']; netPaymentTerm?: InputMaybe; paymentProvider?: InputMaybe; + paymentProviderCode?: InputMaybe; phone?: InputMaybe; providerCustomer?: InputMaybe; state?: InputMaybe; @@ -3674,10 +3798,13 @@ export type UpdateCustomerWalletInput = { recurringTransactionRules?: InputMaybe>; }; -/** Autogenerated input type of UpdateGocardlessPaymentProvider */ +/** Update input arguments */ export type UpdateGocardlessPaymentProviderInput = { /** A unique identifier for the client performing the mutation. */ clientMutationId?: InputMaybe; + code?: InputMaybe; + id: Scalars['ID']['input']; + name?: InputMaybe; successRedirectUrl?: InputMaybe; }; @@ -3744,10 +3871,13 @@ export type UpdateRecurringTransactionRuleInput = { thresholdCredits?: InputMaybe; }; -/** Autogenerated input type of UpdateStripePaymentProvider */ +/** Update input arguments */ export type UpdateStripePaymentProviderInput = { /** A unique identifier for the client performing the mutation. */ clientMutationId?: InputMaybe; + code?: InputMaybe; + id: Scalars['ID']['input']; + name?: InputMaybe; successRedirectUrl?: InputMaybe; }; @@ -4103,9 +4233,16 @@ export type GetCustomerInvoicesQueryVariables = Exact<{ export type GetCustomerInvoicesQuery = { __typename?: 'Query', customerInvoices: { __typename?: 'InvoiceCollection', collection: Array<{ __typename?: 'Invoice', id: string, status: InvoiceStatusTypeEnum, paymentStatus: InvoicePaymentStatusTypeEnum, number: string, issuingDate: any, totalAmountCents: any, currency?: CurrencyEnum | null, voidable: boolean, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, name?: string | null } }>, metadata: { __typename?: 'CollectionMetadata', currentPage: number, totalCount: number, totalPages: number } } }; -export type CustomerItemFragment = { __typename?: 'Customer', id: string, name?: string | null, externalId: string, createdAt: any, activeSubscriptionsCount: number, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }; +export type CustomerItemFragment = { __typename?: 'Customer', id: string, name?: string | null, externalId: string, createdAt: any, activeSubscriptionsCount: number, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }; + +export type CustomerMainInfosFragment = { __typename?: 'Customer', id: string, name?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, phone?: string | null, email?: string | null, currency?: CurrencyEnum | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, url?: string | null, zipcode?: string | null, paymentProvider?: ProviderTypeEnum | null, timezone?: TimezoneEnum | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string }> | null }; + +export type IntegrationsListForCustomerMainInfosQueryVariables = Exact<{ + limit?: InputMaybe; +}>; + -export type CustomerMainInfosFragment = { __typename?: 'Customer', id: string, name?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, phone?: string | null, email?: string | null, currency?: CurrencyEnum | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, url?: string | null, zipcode?: string | null, paymentProvider?: ProviderTypeEnum | null, timezone?: TimezoneEnum | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string }> | null }; +export type IntegrationsListForCustomerMainInfosQuery = { __typename?: 'Query', paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider', id: string, name: string, code: string } | { __typename?: 'GocardlessProvider', id: string, name: string, code: string } | { __typename?: 'StripeProvider', id: string, name: string, code: string }> } | null }; export type CustomerAppliedTaxRatesForSettingsFragment = { __typename?: 'Customer', id: string, taxes?: Array<{ __typename?: 'Tax', id: string, name: string, code: string, rate: number, autoGenerated: boolean }> | null }; @@ -4349,7 +4486,7 @@ export type UpdateInvoicePaymentStatusMutationVariables = Exact<{ }>; -export type UpdateInvoicePaymentStatusMutation = { __typename?: 'Mutation', updateInvoice?: { __typename?: 'Invoice', id: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, number: string, issuingDate: any, totalAmountCents: any, currency?: CurrencyEnum | null, voidable: boolean, invoiceType: InvoiceTypeEnum, refundableAmountCents: any, creditableAmountCents: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, customer: { __typename?: 'Customer', id: string, name?: string | null, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, description?: string | null, groupName?: string | null, invoiceName?: string | null, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, description?: string | null, invoiceName?: string | null, itemName: string, preciseUnitAmount: number, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; +export type UpdateInvoicePaymentStatusMutation = { __typename?: 'Mutation', updateInvoice?: { __typename?: 'Invoice', id: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, number: string, issuingDate: any, totalAmountCents: any, currency?: CurrencyEnum | null, voidable: boolean, invoiceType: InvoiceTypeEnum, refundableAmountCents: any, creditableAmountCents: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, versionNumber: number, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, customer: { __typename?: 'Customer', id: string, name?: string | null, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, description?: string | null, feeType: FeeTypesEnum, itemName: string, preciseUnitAmount: number, eventsCount?: any | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null, interval: PlanInterval } } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; export type InvoiceForFinalizeInvoiceFragment = { __typename?: 'Invoice', id: string, issuingDate: any, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum } }; @@ -4358,20 +4495,12 @@ export type FinalizeInvoiceMutationVariables = Exact<{ }>; -export type FinalizeInvoiceMutation = { __typename?: 'Mutation', finalizeInvoice?: { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, description?: string | null, groupName?: string | null, invoiceName?: string | null, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, description?: string | null, invoiceName?: string | null, itemName: string, preciseUnitAmount: number, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; +export type FinalizeInvoiceMutation = { __typename?: 'Mutation', finalizeInvoice?: { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, versionNumber: number, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, description?: string | null, feeType: FeeTypesEnum, itemName: string, preciseUnitAmount: number, eventsCount?: any | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null, interval: PlanInterval } } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; export type InvoiceForCreditNotesTableFragment = { __typename?: 'Invoice', id: string, customer: { __typename?: 'Customer', id: string }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null }; export type InvoiceForInvoiceInfosFragment = { __typename?: 'Invoice', number: string, issuingDate: any, paymentDueDate: any, status: InvoiceStatusTypeEnum, paymentStatus: InvoicePaymentStatusTypeEnum, customer: { __typename?: 'Customer', id: string, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, applicableTimezone: TimezoneEnum, deletedAt?: any | null } }; -export type FeeForInvoiceDetailsTableFragment = { __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }; - -export type InvoiceForDetailsTableFragment = { __typename?: 'Invoice', invoiceType: InvoiceTypeEnum, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, totalAmountCents: any, currency?: CurrencyEnum | null, issuingDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, description?: string | null, groupName?: string | null, invoiceName?: string | null, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null, customer: { __typename?: 'Customer', id: string, currency?: CurrencyEnum | null, applicableTimezone: TimezoneEnum }, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, description?: string | null, invoiceName?: string | null, itemName: string, preciseUnitAmount: number, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null }; - -export type InvoiceForDetailsTableFeeFragment = { __typename?: 'Invoice', invoiceType: InvoiceTypeEnum, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, totalAmountCents: any, currency?: CurrencyEnum | null, issuingDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean } | null }> | null, customer: { __typename?: 'Customer', id: string, currency?: CurrencyEnum | null, applicableTimezone: TimezoneEnum }, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null }; - -export type InvoiceForDetailsTableFooterFragment = { __typename?: 'Invoice', couponsAmountCents: any, creditNotesAmountCents: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, totalAmountCents: any, currency?: CurrencyEnum | null, prepaidCreditAmountCents: any, versionNumber: number, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null }; - export type InvoiceListItemFragment = { __typename?: 'Invoice', id: string, status: InvoiceStatusTypeEnum, paymentStatus: InvoicePaymentStatusTypeEnum, number: string, issuingDate: any, totalAmountCents: any, currency?: CurrencyEnum | null, voidable: boolean, customer: { __typename?: 'Customer', id: string, name?: string | null, applicableTimezone: TimezoneEnum } }; export type DownloadInvoiceItemMutationVariables = Exact<{ @@ -4399,7 +4528,25 @@ export type VoidInvoiceMutationVariables = Exact<{ }>; -export type VoidInvoiceMutation = { __typename?: 'Mutation', voidInvoice?: { __typename?: 'Invoice', id: string, status: InvoiceStatusTypeEnum, paymentStatus: InvoicePaymentStatusTypeEnum, number: string, issuingDate: any, totalAmountCents: any, currency?: CurrencyEnum | null, voidable: boolean, invoiceType: InvoiceTypeEnum, refundableAmountCents: any, creditableAmountCents: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, customer: { __typename?: 'Customer', id: string, name?: string | null, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, description?: string | null, groupName?: string | null, invoiceName?: string | null, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, description?: string | null, invoiceName?: string | null, itemName: string, preciseUnitAmount: number, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; +export type VoidInvoiceMutation = { __typename?: 'Mutation', voidInvoice?: { __typename?: 'Invoice', id: string, status: InvoiceStatusTypeEnum, paymentStatus: InvoicePaymentStatusTypeEnum, number: string, issuingDate: any, totalAmountCents: any, currency?: CurrencyEnum | null, voidable: boolean, invoiceType: InvoiceTypeEnum, refundableAmountCents: any, creditableAmountCents: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, versionNumber: number, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, customer: { __typename?: 'Customer', id: string, name?: string | null, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, description?: string | null, feeType: FeeTypesEnum, itemName: string, preciseUnitAmount: number, eventsCount?: any | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null, interval: PlanInterval } } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; + +export type FeeForInvoiceDetailsTableFragment = { __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }; + +export type InvoiceForDetailsTableFragment = { __typename?: 'Invoice', invoiceType: InvoiceTypeEnum, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, totalAmountCents: any, currency?: CurrencyEnum | null, issuingDate: any, versionNumber: number, couponsAmountCents: any, creditNotesAmountCents: any, status: InvoiceStatusTypeEnum, prepaidCreditAmountCents: any, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null, customer: { __typename?: 'Customer', id: string, currency?: CurrencyEnum | null, applicableTimezone: TimezoneEnum }, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, description?: string | null, feeType: FeeTypesEnum, itemName: string, preciseUnitAmount: number, eventsCount?: any | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null, interval: PlanInterval } } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null }; + +export type FeeForInvoiceDetailsTableBodyLineFragment = { __typename?: 'Fee', id: string, units: number, preciseUnitAmount: number, amountCents: any, eventsCount?: any | null, charge?: { __typename?: 'Charge', id: string, chargeModel: ChargeModelEnum, minAmountCents: any, payInAdvance: boolean, prorated: boolean } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }; + +export type FeeForInvoiceDetailsTableBodyLineGraduatedFragment = { __typename?: 'Fee', id: string, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, amountDetails?: { __typename?: 'FeeAmountDetails', graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }; + +export type FeeForInvoiceDetailsTableBodyLineGraduatedPercentageFragment = { __typename?: 'Fee', id: string, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, amountDetails?: { __typename?: 'FeeAmountDetails', graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }; + +export type FeeForInvoiceDetailsTableBodyLinePackageFragment = { __typename?: 'Fee', id: string, units: number, amountCents: any, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, amountDetails?: { __typename?: 'FeeAmountDetails', freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null } | null }; + +export type FeeForInvoiceDetailsTableBodyLinePercentageFragment = { __typename?: 'Fee', id: string, units: number, amountCents: any, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, amountDetails?: { __typename?: 'FeeAmountDetails', fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, freeUnits?: string | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, paidUnits?: string | null, perUnitTotalAmount?: string | null, rate?: string | null, units?: string | null } | null }; + +export type FeeForInvoiceDetailsTableBodyLineVolumeFragment = { __typename?: 'Fee', id: string, units: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null } | null }; + +export type InvoiceForDetailsTableFooterFragment = { __typename?: 'Invoice', couponsAmountCents: any, creditNotesAmountCents: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, totalAmountCents: any, currency?: CurrencyEnum | null, invoiceType: InvoiceTypeEnum, status: InvoiceStatusTypeEnum, prepaidCreditAmountCents: any, versionNumber: number, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null }; export type TaxForPlanChargeAccordionFragment = { __typename?: 'Tax', id: string, code: string, name: string, rate: number }; @@ -4598,12 +4745,28 @@ export type UpdateOrganizationLogoMutationVariables = Exact<{ export type UpdateOrganizationLogoMutation = { __typename?: 'Mutation', updateOrganization?: { __typename?: 'Organization', id: string, logoUrl?: string | null } | null }; +export type AddAdyenProviderDialogFragment = { __typename?: 'AdyenProvider', id: string, name: string, code: string, apiKey?: string | null, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string }; + +export type GetProviderByCodeForAdyenQueryVariables = Exact<{ + code?: InputMaybe; +}>; + + +export type GetProviderByCodeForAdyenQuery = { __typename?: 'Query', paymentProvider?: { __typename?: 'AdyenProvider', id: string } | { __typename?: 'GocardlessProvider', id: string } | { __typename?: 'StripeProvider', id: string } | null }; + export type AddAdyenApiKeyMutationVariables = Exact<{ input: AddAdyenPaymentProviderInput; }>; -export type AddAdyenApiKeyMutation = { __typename?: 'Mutation', addAdyenPaymentProvider?: { __typename?: 'AdyenProvider', id: string, apiKey: string, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string } | null }; +export type AddAdyenApiKeyMutation = { __typename?: 'Mutation', addAdyenPaymentProvider?: { __typename?: 'AdyenProvider', id: string, name: string, code: string, apiKey?: string | null, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string, successRedirectUrl?: string | null } | null }; + +export type UpdateAdyenApiKeyMutationVariables = Exact<{ + input: UpdateAdyenPaymentProviderInput; +}>; + + +export type UpdateAdyenApiKeyMutation = { __typename?: 'Mutation', updateAdyenPaymentProvider?: { __typename?: 'AdyenProvider', id: string, name: string, code: string, apiKey?: string | null, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string, successRedirectUrl?: string | null } | null }; export type AdyenForCreateAndEditSuccessRedirectUrlFragment = { __typename?: 'AdyenProvider', id: string, successRedirectUrl?: string | null }; @@ -4632,26 +4795,71 @@ export type UpdateStripePaymentProviderMutationVariables = Exact<{ export type UpdateStripePaymentProviderMutation = { __typename?: 'Mutation', updateStripePaymentProvider?: { __typename?: 'StripeProvider', id: string, successRedirectUrl?: string | null } | null }; -export type UpdateOrgaForTagoTaxManagementMutationVariables = Exact<{ +export type AddGocardlessProviderDialogFragment = { __typename?: 'GocardlessProvider', id: string, name: string, code: string }; + +export type GetProviderByCodeForGocardlessQueryVariables = Exact<{ + code?: InputMaybe; +}>; + + +export type GetProviderByCodeForGocardlessQuery = { __typename?: 'Query', paymentProvider?: { __typename?: 'AdyenProvider', id: string } | { __typename?: 'GocardlessProvider', id: string } | { __typename?: 'StripeProvider', id: string } | null }; + +export type UpdateGocardlessApiKeyMutationVariables = Exact<{ + input: UpdateGocardlessPaymentProviderInput; +}>; + + +export type UpdateGocardlessApiKeyMutation = { __typename?: 'Mutation', updateGocardlessPaymentProvider?: { __typename?: 'GocardlessProvider', id: string, name: string, code: string, successRedirectUrl?: string | null, webhookSecret?: string | null } | null }; + +export type UpdateOrgaForLagoTaxManagementMutationVariables = Exact<{ input: UpdateOrganizationInput; }>; -export type UpdateOrgaForTagoTaxManagementMutation = { __typename?: 'Mutation', updateOrganization?: { __typename?: 'Organization', id: string } | null }; +export type UpdateOrgaForLagoTaxManagementMutation = { __typename?: 'Mutation', updateOrganization?: { __typename?: 'Organization', id: string } | null }; + +export type AddStripeProviderDialogFragment = { __typename?: 'StripeProvider', id: string, name: string, code: string, secretKey?: string | null }; + +export type GetProviderByCodeForStripeQueryVariables = Exact<{ + code?: InputMaybe; +}>; + + +export type GetProviderByCodeForStripeQuery = { __typename?: 'Query', paymentProvider?: { __typename?: 'AdyenProvider', id: string } | { __typename?: 'GocardlessProvider', id: string } | { __typename?: 'StripeProvider', id: string } | null }; export type AddStripeApiKeyMutationVariables = Exact<{ input: AddStripePaymentProviderInput; }>; -export type AddStripeApiKeyMutation = { __typename?: 'Mutation', addStripePaymentProvider?: { __typename?: 'StripeProvider', id: string, secretKey: string, createCustomers: boolean, successRedirectUrl?: string | null } | null }; +export type AddStripeApiKeyMutation = { __typename?: 'Mutation', addStripePaymentProvider?: { __typename?: 'StripeProvider', id: string, name: string, code: string, secretKey?: string | null, successRedirectUrl?: string | null } | null }; + +export type UpdateStripeApiKeyMutationVariables = Exact<{ + input: UpdateStripePaymentProviderInput; +}>; + + +export type UpdateStripeApiKeyMutation = { __typename?: 'Mutation', updateStripePaymentProvider?: { __typename?: 'StripeProvider', id: string, name: string, code: string, secretKey?: string | null, successRedirectUrl?: string | null } | null }; + +export type DeleteAdyenIntegrationDialogFragment = { __typename?: 'AdyenProvider', id: string, name: string }; + +export type DeleteAdyenIntegrationMutationVariables = Exact<{ + input: DestroyPaymentProviderInput; +}>; + + +export type DeleteAdyenIntegrationMutation = { __typename?: 'Mutation', destroyPaymentProvider?: { __typename?: 'DestroyPaymentProviderPayload', id?: string | null } | null }; -export type DeleteAdyenMutationVariables = Exact<{ +export type DeleteGocardlessIntegrationDialogFragment = { __typename?: 'GocardlessProvider', id: string, name: string }; + +export type DeleteGocardlessMutationVariables = Exact<{ input: DestroyPaymentProviderInput; }>; -export type DeleteAdyenMutation = { __typename?: 'Mutation', destroyPaymentProvider?: { __typename?: 'DestroyPaymentProviderPayload', id?: string | null } | null }; +export type DeleteGocardlessMutation = { __typename?: 'Mutation', destroyPaymentProvider?: { __typename?: 'DestroyPaymentProviderPayload', id?: string | null } | null }; + +export type DeleteStripeIntegrationDialogFragment = { __typename?: 'StripeProvider', id: string, name: string }; export type DeleteStripeMutationVariables = Exact<{ input: DestroyPaymentProviderInput; @@ -4745,21 +4953,23 @@ export type GetWalletTransactionsQuery = { __typename?: 'Query', walletTransacti export type WalletInfosForTransactionsFragment = { __typename?: 'Wallet', id: string, currency: CurrencyEnum, status: WalletStatusEnum }; -export type CurrentUserFragment = { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, timezone?: TimezoneEnum | null }> | null }; +export type CurrentUserFragment = { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, name: string, timezone?: TimezoneEnum | null }> | null }; + +export type InvoiceSubscriptionFormatingFragment = { __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, billableMetric: { __typename?: 'BillableMetric', id: string, name: string } } | null, subscription?: { __typename?: 'Subscription', id: string, plan: { __typename?: 'Plan', id: string, interval: PlanInterval } } | null }> | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } }; export type CreateSubscriptionMutationVariables = Exact<{ input: CreateSubscriptionInput; }>; -export type CreateSubscriptionMutation = { __typename?: 'Mutation', createSubscription?: { __typename?: 'Subscription', id: string, customer: { __typename?: 'Customer', id: string, activeSubscriptionsCount: number, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } } | null }; +export type CreateSubscriptionMutation = { __typename?: 'Mutation', createSubscription?: { __typename?: 'Subscription', id: string, customer: { __typename?: 'Customer', id: string, activeSubscriptionsCount: number, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } } | null }; export type UpdateSubscriptionMutationVariables = Exact<{ input: UpdateSubscriptionInput; }>; -export type UpdateSubscriptionMutation = { __typename?: 'Mutation', updateSubscription?: { __typename?: 'Subscription', id: string, customer: { __typename?: 'Customer', id: string, activeSubscriptionsCount: number, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } } | null }; +export type UpdateSubscriptionMutation = { __typename?: 'Mutation', updateSubscription?: { __typename?: 'Subscription', id: string, customer: { __typename?: 'Customer', id: string, activeSubscriptionsCount: number, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } } | null }; export type GetSinglePlanQueryVariables = Exact<{ id: Scalars['ID']['input']; @@ -4869,21 +5079,28 @@ export type UpdateCouponMutationVariables = Exact<{ export type UpdateCouponMutation = { __typename?: 'Mutation', updateCoupon?: { __typename?: 'Coupon', id: string, name: string, customersCount: number, status: CouponStatusEnum, amountCurrency?: CurrencyEnum | null, amountCents?: any | null, appliedCouponsCount: number, expiration: CouponExpiration, expirationAt?: any | null, couponType: CouponTypeEnum, percentageRate?: number | null, frequency: CouponFrequency, frequencyDuration?: number | null } | null }; -export type AddCustomerDrawerFragment = { __typename?: 'Customer', id: string, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, name?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }; +export type AddCustomerDrawerFragment = { __typename?: 'Customer', id: string, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, name?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }; export type CreateCustomerMutationVariables = Exact<{ input: CreateCustomerInput; }>; -export type CreateCustomerMutation = { __typename?: 'Mutation', createCustomer?: { __typename?: 'Customer', id: string, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, name?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, createdAt: any, activeSubscriptionsCount: number, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } | null }; +export type CreateCustomerMutation = { __typename?: 'Mutation', createCustomer?: { __typename?: 'Customer', id: string, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, name?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, createdAt: any, activeSubscriptionsCount: number, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } | null }; export type UpdateCustomerMutationVariables = Exact<{ input: UpdateCustomerInput; }>; -export type UpdateCustomerMutation = { __typename?: 'Mutation', updateCustomer?: { __typename?: 'Customer', id: string, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, name?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, createdAt: any, activeSubscriptionsCount: number, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } | null }; +export type UpdateCustomerMutation = { __typename?: 'Mutation', updateCustomer?: { __typename?: 'Customer', id: string, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalId: string, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, name?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, createdAt: any, activeSubscriptionsCount: number, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } | null }; + +export type IntegrationsListForCustomerCreateEditQueryVariables = Exact<{ + limit?: InputMaybe; +}>; + + +export type IntegrationsListForCustomerCreateEditQuery = { __typename?: 'Query', paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename: 'AdyenProvider', id: string, name: string, code: string } | { __typename: 'GocardlessProvider', id: string, name: string, code: string } | { __typename: 'StripeProvider', id: string, name: string, code: string }> } | null }; export type TaxFormFragment = { __typename?: 'Tax', id: string, code: string, description?: string | null, name: string, rate: number, customersCount: number }; @@ -4936,14 +5153,14 @@ export type GetOrganizationInfosQueryVariables = Exact<{ [key: string]: never; } export type GetOrganizationInfosQuery = { __typename?: 'Query', organization?: { __typename?: 'Organization', id: string, name: string, logoUrl?: string | null, timezone?: TimezoneEnum | null, defaultCurrency: CurrencyEnum } | null }; -export type AllInvoiceDetailsForCustomerInvoiceDetailsFragment = { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, description?: string | null, groupName?: string | null, invoiceName?: string | null, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, description?: string | null, invoiceName?: string | null, itemName: string, preciseUnitAmount: number, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null }; +export type AllInvoiceDetailsForCustomerInvoiceDetailsFragment = { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, versionNumber: number, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, description?: string | null, feeType: FeeTypesEnum, itemName: string, preciseUnitAmount: number, eventsCount?: any | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null, interval: PlanInterval } } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null }; export type GetInvoiceDetailsQueryVariables = Exact<{ id: Scalars['ID']['input']; }>; -export type GetInvoiceDetailsQuery = { __typename?: 'Query', invoice?: { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, description?: string | null, groupName?: string | null, invoiceName?: string | null, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, description?: string | null, invoiceName?: string | null, itemName: string, preciseUnitAmount: number, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; +export type GetInvoiceDetailsQuery = { __typename?: 'Query', invoice?: { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, versionNumber: number, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, description?: string | null, feeType: FeeTypesEnum, itemName: string, preciseUnitAmount: number, eventsCount?: any | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null, interval: PlanInterval } } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; export type DownloadInvoiceMutationVariables = Exact<{ input: DownloadInvoiceInput; @@ -4957,7 +5174,7 @@ export type RefreshInvoiceMutationVariables = Exact<{ }>; -export type RefreshInvoiceMutation = { __typename?: 'Mutation', refreshInvoice?: { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, versionNumber: number, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, itemName: string, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, description?: string | null, groupName?: string | null, invoiceName?: string | null, preciseUnitAmount: number, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, invoiceDisplayName?: string | null, groupName?: string | null, description?: string | null, invoiceName?: string | null, itemName: string, preciseUnitAmount: number, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; +export type RefreshInvoiceMutation = { __typename?: 'Mutation', refreshInvoice?: { __typename?: 'Invoice', id: string, invoiceType: InvoiceTypeEnum, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, status: InvoiceStatusTypeEnum, totalAmountCents: any, currency?: CurrencyEnum | null, refundableAmountCents: any, creditableAmountCents: any, voidable: boolean, issuingDate: any, subTotalExcludingTaxesAmountCents: any, subTotalIncludingTaxesAmountCents: any, versionNumber: number, paymentDueDate: any, couponsAmountCents: any, creditNotesAmountCents: any, prepaidCreditAmountCents: any, customer: { __typename?: 'Customer', id: string, applicableTimezone: TimezoneEnum, currency?: CurrencyEnum | null, name?: string | null, legalNumber?: string | null, legalName?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, state?: string | null, country?: CountryCode | null, city?: string | null, zipcode?: string | null, deletedAt?: any | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, displayInInvoice: boolean, key: string, value: string }> | null }, creditNotes?: Array<{ __typename?: 'CreditNote', id: string, couponsAdjustmentAmountCents: any, number: string, subTotalExcludingTaxesAmountCents: any, currency: CurrencyEnum, totalAmountCents: any, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, groupName?: string | null, itemName: string, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> }> | null, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, description?: string | null, feeType: FeeTypesEnum, groupName?: string | null, invoiceDisplayName?: string | null, invoiceName?: string | null, itemName: string, units: number, preciseUnitAmount: number, eventsCount?: any | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, minAmountCents: any, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null, invoiceSubscriptions?: Array<{ __typename?: 'InvoiceSubscription', fromDatetime?: any | null, toDatetime?: any | null, chargesFromDatetime?: any | null, chargesToDatetime?: any | null, inAdvanceChargesFromDatetime?: any | null, inAdvanceChargesToDatetime?: any | null, subscription: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, interval: PlanInterval, amountCents: any, amountCurrency: CurrencyEnum, invoiceDisplayName?: string | null } }, fees?: Array<{ __typename?: 'Fee', id: string, amountCents: any, invoiceName?: string | null, invoiceDisplayName?: string | null, groupName?: string | null, units: number, description?: string | null, feeType: FeeTypesEnum, itemName: string, preciseUnitAmount: number, eventsCount?: any | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null, interval: PlanInterval } } | null, charge?: { __typename?: 'Charge', id: string, payInAdvance: boolean, minAmountCents: any, invoiceDisplayName?: string | null, chargeModel: ChargeModelEnum, prorated: boolean, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxRate: number }> | null, trueUpFee?: { __typename?: 'Fee', id: string } | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null, amountDetails?: { __typename?: 'FeeAmountDetails', flatUnitAmount?: string | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, freeUnits?: string | null, paidUnits?: string | null, perPackageSize?: number | null, perPackageUnitAmount?: string | null, fixedFeeTotalAmount?: string | null, fixedFeeUnitAmount?: string | null, freeEvents?: number | null, minMaxAdjustmentTotalAmount?: string | null, paidEvents?: number | null, rate?: string | null, units?: string | null, graduatedRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitAmount?: string | null, perUnitTotalAmount?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null, graduatedPercentageRanges?: Array<{ __typename?: 'FeeAmountDetailsGraduatedPercentageRange', flatUnitAmount?: string | null, fromValue?: number | null, perUnitTotalAmount?: string | null, rate?: string | null, toValue?: number | null, totalWithFlatAmount?: string | null, units?: string | null }> | null } | null }> | null }> | null, metadata?: Array<{ __typename?: 'InvoiceMetadata', id: string, key: string, value: string }> | null, appliedTaxes?: Array<{ __typename?: 'InvoiceAppliedTax', id: string, amountCents: any, feesAmountCents: any, taxRate: number, taxName: string }> | null } | null }; export type SideNavInfosQueryVariables = Exact<{ [key: string]: never; }>; @@ -5064,16 +5281,16 @@ export type GetCreditNoteQueryVariables = Exact<{ }>; -export type GetCreditNoteQuery = { __typename?: 'Query', creditNote?: { __typename?: 'CreditNote', id: string, balanceAmountCents: any, canBeVoided: boolean, couponsAdjustmentAmountCents: any, createdAt: any, creditAmountCents: any, creditStatus?: CreditNoteCreditStatusEnum | null, currency: CurrencyEnum, number: string, refundAmountCents: any, refundedAt?: any | null, refundStatus?: CreditNoteRefundStatusEnum | null, subTotalExcludingTaxesAmountCents: any, totalAmountCents: any, customer: { __typename?: 'Customer', id: string, name?: string | null, deletedAt?: any | null, applicableTimezone: TimezoneEnum }, invoice?: { __typename?: 'Invoice', id: string, number: string } | null, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, itemName: string, groupName?: string | null, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> } | null }; +export type GetCreditNoteQuery = { __typename?: 'Query', creditNote?: { __typename?: 'CreditNote', id: string, balanceAmountCents: any, canBeVoided: boolean, couponsAdjustmentAmountCents: any, createdAt: any, creditAmountCents: any, creditStatus?: CreditNoteCreditStatusEnum | null, currency: CurrencyEnum, number: string, refundAmountCents: any, refundedAt?: any | null, refundStatus?: CreditNoteRefundStatusEnum | null, subTotalExcludingTaxesAmountCents: any, totalAmountCents: any, customer: { __typename?: 'Customer', id: string, name?: string | null, deletedAt?: any | null, applicableTimezone: TimezoneEnum }, invoice?: { __typename?: 'Invoice', id: string, number: string } | null, appliedTaxes?: Array<{ __typename?: 'CreditNoteAppliedTax', id: string, amountCents: any, baseAmountCents: any, taxRate: number, taxName: string }> | null, items: Array<{ __typename?: 'CreditNoteItem', amountCents: any, amountCurrency: CurrencyEnum, fee: { __typename?: 'Fee', id: string, amountCents: any, eventsCount?: any | null, units: number, feeType: FeeTypesEnum, itemName: string, groupName?: string | null, invoiceName?: string | null, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, tax: { __typename?: 'Tax', id: string, rate: number } }> | null, trueUpParentFee?: { __typename?: 'Fee', id: string } | null, charge?: { __typename?: 'Charge', id: string, billableMetric: { __typename?: 'BillableMetric', id: string, name: string, aggregationType: AggregationTypeEnum } } | null, subscription?: { __typename?: 'Subscription', id: string, name?: string | null, plan: { __typename?: 'Plan', id: string, name: string, invoiceDisplayName?: string | null } } | null, group?: { __typename?: 'Group', id: string, key?: string | null, value: string } | null } }> } | null }; -export type CustomerDetailsFragment = { __typename?: 'Customer', id: string, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }; +export type CustomerDetailsFragment = { __typename?: 'Customer', id: string, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }; export type GetCustomerQueryVariables = Exact<{ id: Scalars['ID']['input']; }>; -export type GetCustomerQuery = { __typename?: 'Query', customer?: { __typename?: 'Customer', id: string, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } | null }; +export type GetCustomerQuery = { __typename?: 'Query', customer?: { __typename?: 'Customer', id: string, name?: string | null, externalId: string, hasActiveWallet: boolean, currency?: CurrencyEnum | null, hasCreditNotes: boolean, creditNotesCreditsAvailableCount: number, creditNotesBalanceAmountCents: any, applicableTimezone: TimezoneEnum, addressLine1?: string | null, addressLine2?: string | null, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null } | null }; export type GenerateCustomerPortalUrlMutationVariables = Exact<{ input: GenerateCustomerPortalUrlInput; @@ -5108,7 +5325,7 @@ export type CustomersQueryVariables = Exact<{ }>; -export type CustomersQuery = { __typename?: 'Query', customers: { __typename?: 'CustomerCollection', metadata: { __typename?: 'CollectionMetadata', currentPage: number, totalPages: number }, collection: Array<{ __typename?: 'Customer', id: string, name?: string | null, externalId: string, createdAt: any, activeSubscriptionsCount: number, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }> } }; +export type CustomersQuery = { __typename?: 'Query', customers: { __typename?: 'CustomerCollection', metadata: { __typename?: 'CollectionMetadata', currentPage: number, totalPages: number }, collection: Array<{ __typename?: 'Customer', id: string, name?: string | null, externalId: string, createdAt: any, activeSubscriptionsCount: number, addressLine1?: string | null, addressLine2?: string | null, applicableTimezone: TimezoneEnum, canEditAttributes: boolean, city?: string | null, country?: CountryCode | null, currency?: CurrencyEnum | null, email?: string | null, externalSalesforceId?: string | null, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, paymentProvider?: ProviderTypeEnum | null, phone?: string | null, state?: string | null, timezone?: TimezoneEnum | null, zipcode?: string | null, url?: string | null, paymentProviderCode?: string | null, providerCustomer?: { __typename?: 'ProviderCustomer', id: string, providerCustomerId?: string | null, syncWithProvider?: boolean | null, providerPaymentMethods?: Array | null } | null, metadata?: Array<{ __typename?: 'CustomerMetadata', id: string, key: string, value: string, displayInInvoice: boolean }> | null }> } }; export type GetinviteQueryVariables = Exact<{ token: Scalars['String']['input']; @@ -5122,7 +5339,7 @@ export type AcceptInviteMutationVariables = Exact<{ }>; -export type AcceptInviteMutation = { __typename?: 'Mutation', acceptInvite?: { __typename?: 'RegisterUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, timezone?: TimezoneEnum | null }> | null } } | null }; +export type AcceptInviteMutation = { __typename?: 'Mutation', acceptInvite?: { __typename?: 'RegisterUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, name: string, timezone?: TimezoneEnum | null }> | null } } | null }; export type GetInvoiceCreditNotesQueryVariables = Exact<{ invoiceId: Scalars['ID']['input']; @@ -5218,7 +5435,7 @@ export type LoginUserMutationVariables = Exact<{ }>; -export type LoginUserMutation = { __typename?: 'Mutation', loginUser?: { __typename?: 'LoginUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, timezone?: TimezoneEnum | null }> | null } } | null }; +export type LoginUserMutation = { __typename?: 'Mutation', loginUser?: { __typename?: 'LoginUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, name: string, timezone?: TimezoneEnum | null }> | null } } | null }; export type GetPortalLocaleQueryVariables = Exact<{ [key: string]: never; }>; @@ -5237,14 +5454,14 @@ export type ResetPasswordMutationVariables = Exact<{ }>; -export type ResetPasswordMutation = { __typename?: 'Mutation', resetPassword?: { __typename?: 'LoginUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, timezone?: TimezoneEnum | null }> | null } } | null }; +export type ResetPasswordMutation = { __typename?: 'Mutation', resetPassword?: { __typename?: 'LoginUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, name: string, timezone?: TimezoneEnum | null }> | null } } | null }; export type SignupMutationVariables = Exact<{ input: RegisterUserInput; }>; -export type SignupMutation = { __typename?: 'Mutation', registerUser?: { __typename?: 'RegisterUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, timezone?: TimezoneEnum | null }> | null } } | null }; +export type SignupMutation = { __typename?: 'Mutation', registerUser?: { __typename?: 'RegisterUser', token: string, user: { __typename?: 'User', id: string, organizations?: Array<{ __typename?: 'Organization', id: string, name: string, timezone?: TimezoneEnum | null }> | null } } | null }; export type GetPortalOrgaInfosQueryVariables = Exact<{ [key: string]: never; }>; @@ -5293,29 +5510,63 @@ export type GetWebhookListQueryVariables = Exact<{ export type GetWebhookListQuery = { __typename?: 'Query', webhookEndpoints: { __typename?: 'WebhookEndpointCollection', collection: Array<{ __typename?: 'WebhookEndpoint', id: string, webhookUrl: string, signatureAlgo?: WebhookEndpointSignatureAlgoEnum | null }> } }; -export type AdyenIntegrationFragment = { __typename?: 'AdyenProvider', id: string, apiKey: string, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string }; +export type AdyenIntegrationDetailsFragment = { __typename?: 'AdyenProvider', id: string, apiKey?: string | null, code: string, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string, successRedirectUrl?: string | null, name: string }; + +export type GetAdyenIntegrationsDetailsQueryVariables = Exact<{ + id: Scalars['ID']['input']; + limit?: InputMaybe; + type?: InputMaybe; +}>; + + +export type GetAdyenIntegrationsDetailsQuery = { __typename?: 'Query', paymentProvider?: { __typename?: 'AdyenProvider', id: string, apiKey?: string | null, code: string, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string, successRedirectUrl?: string | null, name: string } | { __typename?: 'GocardlessProvider' } | { __typename?: 'StripeProvider' } | null, paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider', id: string } | { __typename?: 'GocardlessProvider' } | { __typename?: 'StripeProvider' }> } | null }; + +export type AdyenIntegrationsFragment = { __typename?: 'AdyenProvider', id: string, name: string, code: string }; + +export type GetAdyenIntegrationsListQueryVariables = Exact<{ + limit?: InputMaybe; + type?: InputMaybe; +}>; -export type AdyenIntegrationsSettingQueryVariables = Exact<{ [key: string]: never; }>; +export type GetAdyenIntegrationsListQuery = { __typename?: 'Query', paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider', id: string, name: string, code: string, apiKey?: string | null, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string } | { __typename?: 'GocardlessProvider' } | { __typename?: 'StripeProvider' }> } | null }; -export type AdyenIntegrationsSettingQuery = { __typename?: 'Query', organization?: { __typename?: 'Organization', id: string, adyenPaymentProvider?: { __typename?: 'AdyenProvider', id: string, successRedirectUrl?: string | null, apiKey: string, hmacKey?: string | null, livePrefix?: string | null, merchantAccount: string } | null } | null }; +export type GocardlessIntegrationDetailsFragment = { __typename?: 'GocardlessProvider', id: string, code: string, name: string, successRedirectUrl?: string | null, webhookSecret?: string | null }; + +export type GetGocardlessIntegrationsDetailsQueryVariables = Exact<{ + id: Scalars['ID']['input']; + limit?: InputMaybe; + type?: InputMaybe; +}>; -export type GocardlessIntegrationsSettingQueryVariables = Exact<{ [key: string]: never; }>; +export type GetGocardlessIntegrationsDetailsQuery = { __typename?: 'Query', paymentProvider?: { __typename?: 'AdyenProvider' } | { __typename?: 'GocardlessProvider', id: string, code: string, name: string, successRedirectUrl?: string | null, webhookSecret?: string | null } | { __typename?: 'StripeProvider' } | null, paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider' } | { __typename?: 'GocardlessProvider', id: string } | { __typename?: 'StripeProvider' }> } | null }; -export type GocardlessIntegrationsSettingQuery = { __typename?: 'Query', organization?: { __typename?: 'Organization', id: string, gocardlessPaymentProvider?: { __typename?: 'GocardlessProvider', id: string, hasAccessToken: boolean, webhookSecret?: string | null, successRedirectUrl?: string | null } | null } | null }; +export type GocardlessIntegrationOauthCallbackFragment = { __typename?: 'GocardlessProvider', id: string, name: string, code: string }; -export type AddGocardlessPaymentProviderMutationVariables = Exact<{ +export type AddGocardlessApiKeyMutationVariables = Exact<{ input: AddGocardlessPaymentProviderInput; }>; -export type AddGocardlessPaymentProviderMutation = { __typename?: 'Mutation', addGocardlessPaymentProvider?: { __typename?: 'GocardlessProvider', id: string, hasAccessToken: boolean, webhookSecret?: string | null, successRedirectUrl?: string | null } | null }; +export type AddGocardlessApiKeyMutation = { __typename?: 'Mutation', addGocardlessPaymentProvider?: { __typename?: 'GocardlessProvider', id: string, name: string, code: string } | null }; + +export type GocardlessIntegrationsFragment = { __typename?: 'GocardlessProvider', id: string, name: string, code: string }; + +export type GetGocardlessIntegrationsListQueryVariables = Exact<{ + limit?: InputMaybe; + type?: InputMaybe; +}>; + + +export type GetGocardlessIntegrationsListQuery = { __typename?: 'Query', paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider' } | { __typename?: 'GocardlessProvider', id: string, name: string, code: string } | { __typename?: 'StripeProvider' }> } | null }; -export type IntegrationsSettingQueryVariables = Exact<{ [key: string]: never; }>; +export type IntegrationsSettingQueryVariables = Exact<{ + limit?: InputMaybe; +}>; -export type IntegrationsSettingQuery = { __typename?: 'Query', organization?: { __typename?: 'Organization', id: string, euTaxManagement: boolean, country?: CountryCode | null, stripePaymentProvider?: { __typename?: 'StripeProvider', id: string } | null, gocardlessPaymentProvider?: { __typename?: 'GocardlessProvider', id: string } | null, adyenPaymentProvider?: { __typename?: 'AdyenProvider', id: string } | null } | null }; +export type IntegrationsSettingQuery = { __typename?: 'Query', organization?: { __typename?: 'Organization', id: string, euTaxManagement: boolean, country?: CountryCode | null } | null, paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider', id: string } | { __typename?: 'GocardlessProvider', id: string } | { __typename?: 'StripeProvider', id: string }> } | null }; export type GetOrganizationSettingsQueryVariables = Exact<{ appliedToOrganization?: InputMaybe; @@ -5364,19 +5615,26 @@ export type GetOrganizationInformationsQueryVariables = Exact<{ [key: string]: n export type GetOrganizationInformationsQuery = { __typename?: 'Query', organization?: { __typename?: 'Organization', id: string, logoUrl?: string | null, name: string, legalName?: string | null, legalNumber?: string | null, taxIdentificationNumber?: string | null, email?: string | null, addressLine1?: string | null, addressLine2?: string | null, zipcode?: string | null, city?: string | null, state?: string | null, country?: CountryCode | null, timezone?: TimezoneEnum | null } | null }; -export type StripeIntegrationFragment = { __typename?: 'StripeProvider', id: string, secretKey: string, createCustomers: boolean, successRedirectUrl?: string | null }; +export type StripeIntegrationDetailsFragment = { __typename?: 'StripeProvider', id: string, code: string, name: string, secretKey?: string | null, successRedirectUrl?: string | null }; + +export type GetStripeIntegrationsDetailsQueryVariables = Exact<{ + id: Scalars['ID']['input']; + limit?: InputMaybe; + type?: InputMaybe; +}>; -export type StripeIntegrationsSettingQueryVariables = Exact<{ [key: string]: never; }>; +export type GetStripeIntegrationsDetailsQuery = { __typename?: 'Query', paymentProvider?: { __typename?: 'AdyenProvider' } | { __typename?: 'GocardlessProvider' } | { __typename?: 'StripeProvider', id: string, code: string, name: string, secretKey?: string | null, successRedirectUrl?: string | null } | null, paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider' } | { __typename?: 'GocardlessProvider' } | { __typename?: 'StripeProvider', id: string }> } | null }; -export type StripeIntegrationsSettingQuery = { __typename?: 'Query', organization?: { __typename?: 'Organization', id: string, stripePaymentProvider?: { __typename?: 'StripeProvider', id: string, secretKey: string, createCustomers: boolean, successRedirectUrl?: string | null } | null } | null }; +export type StripeIntegrationsFragment = { __typename?: 'StripeProvider', id: string, name: string, code: string }; -export type UpdateStripeIntegrationMutationVariables = Exact<{ - input: AddStripePaymentProviderInput; +export type GetStripeIntegrationsListQueryVariables = Exact<{ + limit?: InputMaybe; + type?: InputMaybe; }>; -export type UpdateStripeIntegrationMutation = { __typename?: 'Mutation', addStripePaymentProvider?: { __typename?: 'StripeProvider', id: string, secretKey: string, createCustomers: boolean, successRedirectUrl?: string | null } | null }; +export type GetStripeIntegrationsListQuery = { __typename?: 'Query', paymentProviders?: { __typename?: 'PaymentProviderCollection', collection: Array<{ __typename?: 'AdyenProvider' } | { __typename?: 'GocardlessProvider' } | { __typename?: 'StripeProvider', id: string, name: string, code: string, secretKey?: string | null }> } | null }; export type GetTaxesQueryVariables = Exact<{ limit?: InputMaybe; @@ -5587,6 +5845,7 @@ export const AddCustomerDrawerFragmentDoc = gql` timezone zipcode url + paymentProviderCode providerCustomer { id providerCustomerId @@ -5916,6 +6175,17 @@ export const EditOrganizationInvoiceTemplateDialogFragmentDoc = gql` } } `; +export const AddAdyenProviderDialogFragmentDoc = gql` + fragment AddAdyenProviderDialog on AdyenProvider { + id + name + code + apiKey + hmacKey + livePrefix + merchantAccount +} + `; export const AdyenForCreateAndEditSuccessRedirectUrlFragmentDoc = gql` fragment AdyenForCreateAndEditSuccessRedirectUrl on AdyenProvider { id @@ -5929,11 +6199,44 @@ export const GocardlessForCreateAndEditSuccessRedirectUrlFragmentDoc = gql` } `; export const StripeForCreateAndEditSuccessRedirectUrlFragmentDoc = gql` - fragment stripeForCreateAndEditSuccessRedirectUrl on StripeProvider { + fragment StripeForCreateAndEditSuccessRedirectUrl on StripeProvider { id successRedirectUrl } `; +export const AddGocardlessProviderDialogFragmentDoc = gql` + fragment AddGocardlessProviderDialog on GocardlessProvider { + id + name + code +} + `; +export const AddStripeProviderDialogFragmentDoc = gql` + fragment AddStripeProviderDialog on StripeProvider { + id + name + code + secretKey +} + `; +export const DeleteAdyenIntegrationDialogFragmentDoc = gql` + fragment DeleteAdyenIntegrationDialog on AdyenProvider { + id + name +} + `; +export const DeleteGocardlessIntegrationDialogFragmentDoc = gql` + fragment DeleteGocardlessIntegrationDialog on GocardlessProvider { + id + name +} + `; +export const DeleteStripeIntegrationDialogFragmentDoc = gql` + fragment DeleteStripeIntegrationDialog on StripeProvider { + id + name +} + `; export const InviteItemFragmentDoc = gql` fragment InviteItem on Invite { id @@ -6061,6 +6364,7 @@ export const CurrentUserFragmentDoc = gql` id organizations { id + name timezone } } @@ -6373,112 +6677,130 @@ export const InvoiceForCreditNotesTableFragmentDoc = gql` } } `; -export const InvoiceForDetailsTableFooterFragmentDoc = gql` - fragment InvoiceForDetailsTableFooter on Invoice { - couponsAmountCents - creditNotesAmountCents - subTotalExcludingTaxesAmountCents - subTotalIncludingTaxesAmountCents - totalAmountCents - currency - prepaidCreditAmountCents - versionNumber +export const FeeForInvoiceDetailsTableBodyLineGraduatedFragmentDoc = gql` + fragment FeeForInvoiceDetailsTableBodyLineGraduated on Fee { + id appliedTaxes { id - amountCents - feesAmountCents taxRate - taxName + } + amountDetails { + graduatedRanges { + flatUnitAmount + fromValue + perUnitAmount + perUnitTotalAmount + toValue + totalWithFlatAmount + units + } } } `; -export const InvoiceForDetailsTableFeeFragmentDoc = gql` - fragment InvoiceForDetailsTableFee on Invoice { - invoiceType - subTotalExcludingTaxesAmountCents - subTotalIncludingTaxesAmountCents - totalAmountCents - currency - issuingDate - ...InvoiceForDetailsTableFooter - fees { +export const FeeForInvoiceDetailsTableBodyLineGraduatedPercentageFragmentDoc = gql` + fragment FeeForInvoiceDetailsTableBodyLineGraduatedPercentage on Fee { + id + appliedTaxes { id - amountCents - itemName - units - feeType - invoiceDisplayName - appliedTaxes { - id - taxRate - } - trueUpFee { - id - } - charge { - id - payInAdvance + taxRate + } + amountDetails { + graduatedPercentageRanges { + flatUnitAmount + fromValue + perUnitTotalAmount + rate + toValue + totalWithFlatAmount + units } } - customer { +} + `; +export const FeeForInvoiceDetailsTableBodyLineVolumeFragmentDoc = gql` + fragment FeeForInvoiceDetailsTableBodyLineVolume on Fee { + id + units + appliedTaxes { id - currency - applicableTimezone + taxRate } - invoiceSubscriptions { - fromDatetime - toDatetime - chargesFromDatetime - chargesToDatetime - inAdvanceChargesFromDatetime - inAdvanceChargesToDatetime - subscription { - id - name - plan { - id - name - interval - amountCents - amountCurrency - } - } - fees { - id - amountCents - eventsCount - units - feeType - invoiceDisplayName - groupName - appliedTaxes { - id - taxRate - } - trueUpFee { - id - } - trueUpParentFee { - id - } - charge { - id - payInAdvance - billableMetric { - id - name - aggregationType - } - } - group { - id - key - value - } - } + amountDetails { + flatUnitAmount + perUnitAmount + perUnitTotalAmount + } +} + `; +export const FeeForInvoiceDetailsTableBodyLinePackageFragmentDoc = gql` + fragment FeeForInvoiceDetailsTableBodyLinePackage on Fee { + id + units + amountCents + appliedTaxes { + id + taxRate + } + amountDetails { + freeUnits + paidUnits + perPackageSize + perPackageUnitAmount + } +} + `; +export const FeeForInvoiceDetailsTableBodyLinePercentageFragmentDoc = gql` + fragment FeeForInvoiceDetailsTableBodyLinePercentage on Fee { + id + units + amountCents + appliedTaxes { + id + taxRate + } + amountDetails { + fixedFeeTotalAmount + fixedFeeUnitAmount + freeEvents + freeUnits + minMaxAdjustmentTotalAmount + paidEvents + paidUnits + perUnitTotalAmount + rate + units } } - ${InvoiceForDetailsTableFooterFragmentDoc}`; + `; +export const FeeForInvoiceDetailsTableBodyLineFragmentDoc = gql` + fragment FeeForInvoiceDetailsTableBodyLine on Fee { + id + units + preciseUnitAmount + amountCents + eventsCount + charge { + id + chargeModel + minAmountCents + payInAdvance + prorated + } + appliedTaxes { + id + taxRate + } + ...FeeForInvoiceDetailsTableBodyLineGraduated + ...FeeForInvoiceDetailsTableBodyLineGraduatedPercentage + ...FeeForInvoiceDetailsTableBodyLineVolume + ...FeeForInvoiceDetailsTableBodyLinePackage + ...FeeForInvoiceDetailsTableBodyLinePercentage +} + ${FeeForInvoiceDetailsTableBodyLineGraduatedFragmentDoc} +${FeeForInvoiceDetailsTableBodyLineGraduatedPercentageFragmentDoc} +${FeeForInvoiceDetailsTableBodyLineVolumeFragmentDoc} +${FeeForInvoiceDetailsTableBodyLinePackageFragmentDoc} +${FeeForInvoiceDetailsTableBodyLinePercentageFragmentDoc}`; export const FeeForInvoiceDetailsTableFragmentDoc = gql` fragment FeeForInvoiceDetailsTable on Fee { id @@ -6516,6 +6838,71 @@ export const FeeForInvoiceDetailsTableFragmentDoc = gql` key value } + ...FeeForInvoiceDetailsTableBodyLine +} + ${FeeForInvoiceDetailsTableBodyLineFragmentDoc}`; +export const InvoiceSubscriptionFormatingFragmentDoc = gql` + fragment InvoiceSubscriptionFormating on InvoiceSubscription { + fromDatetime + toDatetime + chargesFromDatetime + chargesToDatetime + inAdvanceChargesFromDatetime + inAdvanceChargesToDatetime + fees { + id + amountCents + invoiceName + invoiceDisplayName + groupName + units + charge { + id + payInAdvance + minAmountCents + billableMetric { + id + name + } + } + subscription { + id + plan { + id + interval + } + } + } + subscription { + id + name + plan { + id + name + invoiceDisplayName + } + } +} + `; +export const InvoiceForDetailsTableFooterFragmentDoc = gql` + fragment InvoiceForDetailsTableFooter on Invoice { + couponsAmountCents + creditNotesAmountCents + subTotalExcludingTaxesAmountCents + subTotalIncludingTaxesAmountCents + totalAmountCents + currency + invoiceType + status + prepaidCreditAmountCents + versionNumber + appliedTaxes { + id + amountCents + feesAmountCents + taxRate + taxName + } } `; export const InvoiceForDetailsTableFragmentDoc = gql` @@ -6526,8 +6913,7 @@ export const InvoiceForDetailsTableFragmentDoc = gql` totalAmountCents currency issuingDate - ...InvoiceForDetailsTableFee - ...InvoiceForDetailsTableFooter + versionNumber fees { id ...FeeForInvoiceDetailsTable @@ -6569,11 +6955,13 @@ export const InvoiceForDetailsTableFragmentDoc = gql` } ...FeeForInvoiceDetailsTable } + ...InvoiceSubscriptionFormating } + ...InvoiceForDetailsTableFooter } - ${InvoiceForDetailsTableFeeFragmentDoc} -${InvoiceForDetailsTableFooterFragmentDoc} -${FeeForInvoiceDetailsTableFragmentDoc}`; + ${FeeForInvoiceDetailsTableFragmentDoc} +${InvoiceSubscriptionFormatingFragmentDoc} +${InvoiceForDetailsTableFooterFragmentDoc}`; export const InvoiceForInvoiceInfosFragmentDoc = gql` fragment InvoiceForInvoiceInfos on Invoice { number @@ -6978,6 +7366,7 @@ export const CustomerMainInfosFragmentDoc = gql` zipcode paymentProvider timezone + paymentProviderCode providerCustomer { id providerCustomerId @@ -7086,13 +7475,46 @@ export const WebhookLogFragmentDoc = gql` } ${WebhookLogItemFragmentDoc} ${WebhookLogDetailsFragmentDoc}`; -export const AdyenIntegrationFragmentDoc = gql` - fragment AdyenIntegration on AdyenProvider { +export const AdyenIntegrationDetailsFragmentDoc = gql` + fragment AdyenIntegrationDetails on AdyenProvider { id apiKey + code hmacKey livePrefix merchantAccount + successRedirectUrl + name +} + `; +export const AdyenIntegrationsFragmentDoc = gql` + fragment AdyenIntegrations on AdyenProvider { + id + name + code +} + `; +export const GocardlessIntegrationDetailsFragmentDoc = gql` + fragment GocardlessIntegrationDetails on GocardlessProvider { + id + code + name + successRedirectUrl + webhookSecret +} + `; +export const GocardlessIntegrationOauthCallbackFragmentDoc = gql` + fragment GocardlessIntegrationOauthCallback on GocardlessProvider { + id + name + code +} + `; +export const GocardlessIntegrationsFragmentDoc = gql` + fragment GocardlessIntegrations on GocardlessProvider { + id + name + code } `; export const OrganizationInformationsFragmentDoc = gql` @@ -7113,14 +7535,22 @@ export const OrganizationInformationsFragmentDoc = gql` timezone } `; -export const StripeIntegrationFragmentDoc = gql` - fragment StripeIntegration on StripeProvider { +export const StripeIntegrationDetailsFragmentDoc = gql` + fragment StripeIntegrationDetails on StripeProvider { id + code + name secretKey - createCustomers successRedirectUrl } `; +export const StripeIntegrationsFragmentDoc = gql` + fragment StripeIntegrations on StripeProvider { + id + name + code +} + `; export const UserIdentifierDocument = gql` query UserIdentifier { me: currentUser { @@ -7860,6 +8290,62 @@ export type GetCustomerInvoicesQueryHookResult = ReturnType; export type GetCustomerInvoicesSuspenseQueryHookResult = ReturnType; export type GetCustomerInvoicesQueryResult = Apollo.QueryResult; +export const IntegrationsListForCustomerMainInfosDocument = gql` + query integrationsListForCustomerMainInfos($limit: Int) { + paymentProviders(limit: $limit) { + collection { + ... on StripeProvider { + id + name + code + } + ... on GocardlessProvider { + id + name + code + } + ... on AdyenProvider { + id + name + code + } + } + } +} + `; + +/** + * __useIntegrationsListForCustomerMainInfosQuery__ + * + * To run a query within a React component, call `useIntegrationsListForCustomerMainInfosQuery` and pass it any options that fit your needs. + * When your component renders, `useIntegrationsListForCustomerMainInfosQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useIntegrationsListForCustomerMainInfosQuery({ + * variables: { + * limit: // value for 'limit' + * }, + * }); + */ +export function useIntegrationsListForCustomerMainInfosQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(IntegrationsListForCustomerMainInfosDocument, options); + } +export function useIntegrationsListForCustomerMainInfosLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(IntegrationsListForCustomerMainInfosDocument, options); + } +export function useIntegrationsListForCustomerMainInfosSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(IntegrationsListForCustomerMainInfosDocument, options); + } +export type IntegrationsListForCustomerMainInfosQueryHookResult = ReturnType; +export type IntegrationsListForCustomerMainInfosLazyQueryHookResult = ReturnType; +export type IntegrationsListForCustomerMainInfosSuspenseQueryHookResult = ReturnType; +export type IntegrationsListForCustomerMainInfosQueryResult = Apollo.QueryResult; export const GetCustomerSettingsDocument = gql` query getCustomerSettings($id: ID!) { customer(id: $id) { @@ -9869,18 +10355,64 @@ export function useUpdateOrganizationLogoMutation(baseOptions?: Apollo.MutationH export type UpdateOrganizationLogoMutationHookResult = ReturnType; export type UpdateOrganizationLogoMutationResult = Apollo.MutationResult; export type UpdateOrganizationLogoMutationOptions = Apollo.BaseMutationOptions; +export const GetProviderByCodeForAdyenDocument = gql` + query getProviderByCodeForAdyen($code: String) { + paymentProvider(code: $code) { + ... on AdyenProvider { + id + } + ... on GocardlessProvider { + id + } + ... on StripeProvider { + id + } + } +} + `; + +/** + * __useGetProviderByCodeForAdyenQuery__ + * + * To run a query within a React component, call `useGetProviderByCodeForAdyenQuery` and pass it any options that fit your needs. + * When your component renders, `useGetProviderByCodeForAdyenQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetProviderByCodeForAdyenQuery({ + * variables: { + * code: // value for 'code' + * }, + * }); + */ +export function useGetProviderByCodeForAdyenQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetProviderByCodeForAdyenDocument, options); + } +export function useGetProviderByCodeForAdyenLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetProviderByCodeForAdyenDocument, options); + } +export function useGetProviderByCodeForAdyenSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(GetProviderByCodeForAdyenDocument, options); + } +export type GetProviderByCodeForAdyenQueryHookResult = ReturnType; +export type GetProviderByCodeForAdyenLazyQueryHookResult = ReturnType; +export type GetProviderByCodeForAdyenSuspenseQueryHookResult = ReturnType; +export type GetProviderByCodeForAdyenQueryResult = Apollo.QueryResult; export const AddAdyenApiKeyDocument = gql` mutation addAdyenApiKey($input: AddAdyenPaymentProviderInput!) { addAdyenPaymentProvider(input: $input) { id - apiKey - hmacKey - livePrefix - merchantAccount - ...AdyenIntegration + ...AddAdyenProviderDialog + ...AdyenIntegrationDetails } } - ${AdyenIntegrationFragmentDoc}`; + ${AddAdyenProviderDialogFragmentDoc} +${AdyenIntegrationDetailsFragmentDoc}`; export type AddAdyenApiKeyMutationFn = Apollo.MutationFunction; /** @@ -9907,6 +10439,42 @@ export function useAddAdyenApiKeyMutation(baseOptions?: Apollo.MutationHookOptio export type AddAdyenApiKeyMutationHookResult = ReturnType; export type AddAdyenApiKeyMutationResult = Apollo.MutationResult; export type AddAdyenApiKeyMutationOptions = Apollo.BaseMutationOptions; +export const UpdateAdyenApiKeyDocument = gql` + mutation updateAdyenApiKey($input: UpdateAdyenPaymentProviderInput!) { + updateAdyenPaymentProvider(input: $input) { + id + ...AddAdyenProviderDialog + ...AdyenIntegrationDetails + } +} + ${AddAdyenProviderDialogFragmentDoc} +${AdyenIntegrationDetailsFragmentDoc}`; +export type UpdateAdyenApiKeyMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateAdyenApiKeyMutation__ + * + * To run a mutation, you first call `useUpdateAdyenApiKeyMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateAdyenApiKeyMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateAdyenApiKeyMutation, { data, loading, error }] = useUpdateAdyenApiKeyMutation({ + * variables: { + * input: // value for 'input' + * }, + * }); + */ +export function useUpdateAdyenApiKeyMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateAdyenApiKeyDocument, options); + } +export type UpdateAdyenApiKeyMutationHookResult = ReturnType; +export type UpdateAdyenApiKeyMutationResult = Apollo.MutationResult; +export type UpdateAdyenApiKeyMutationOptions = Apollo.BaseMutationOptions; export const UpdateAdyenPaymentProviderDocument = gql` mutation updateAdyenPaymentProvider($input: UpdateAdyenPaymentProviderInput!) { updateAdyenPaymentProvider(input: $input) { @@ -10009,47 +10577,181 @@ export function useUpdateStripePaymentProviderMutation(baseOptions?: Apollo.Muta export type UpdateStripePaymentProviderMutationHookResult = ReturnType; export type UpdateStripePaymentProviderMutationResult = Apollo.MutationResult; export type UpdateStripePaymentProviderMutationOptions = Apollo.BaseMutationOptions; -export const UpdateOrgaForTagoTaxManagementDocument = gql` - mutation updateOrgaForTagoTaxManagement($input: UpdateOrganizationInput!) { +export const GetProviderByCodeForGocardlessDocument = gql` + query getProviderByCodeForGocardless($code: String) { + paymentProvider(code: $code) { + ... on GocardlessProvider { + id + } + ... on AdyenProvider { + id + } + ... on StripeProvider { + id + } + } +} + `; + +/** + * __useGetProviderByCodeForGocardlessQuery__ + * + * To run a query within a React component, call `useGetProviderByCodeForGocardlessQuery` and pass it any options that fit your needs. + * When your component renders, `useGetProviderByCodeForGocardlessQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetProviderByCodeForGocardlessQuery({ + * variables: { + * code: // value for 'code' + * }, + * }); + */ +export function useGetProviderByCodeForGocardlessQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetProviderByCodeForGocardlessDocument, options); + } +export function useGetProviderByCodeForGocardlessLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetProviderByCodeForGocardlessDocument, options); + } +export function useGetProviderByCodeForGocardlessSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(GetProviderByCodeForGocardlessDocument, options); + } +export type GetProviderByCodeForGocardlessQueryHookResult = ReturnType; +export type GetProviderByCodeForGocardlessLazyQueryHookResult = ReturnType; +export type GetProviderByCodeForGocardlessSuspenseQueryHookResult = ReturnType; +export type GetProviderByCodeForGocardlessQueryResult = Apollo.QueryResult; +export const UpdateGocardlessApiKeyDocument = gql` + mutation updateGocardlessApiKey($input: UpdateGocardlessPaymentProviderInput!) { + updateGocardlessPaymentProvider(input: $input) { + id + ...AddGocardlessProviderDialog + ...GocardlessIntegrationDetails + } +} + ${AddGocardlessProviderDialogFragmentDoc} +${GocardlessIntegrationDetailsFragmentDoc}`; +export type UpdateGocardlessApiKeyMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateGocardlessApiKeyMutation__ + * + * To run a mutation, you first call `useUpdateGocardlessApiKeyMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateGocardlessApiKeyMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateGocardlessApiKeyMutation, { data, loading, error }] = useUpdateGocardlessApiKeyMutation({ + * variables: { + * input: // value for 'input' + * }, + * }); + */ +export function useUpdateGocardlessApiKeyMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateGocardlessApiKeyDocument, options); + } +export type UpdateGocardlessApiKeyMutationHookResult = ReturnType; +export type UpdateGocardlessApiKeyMutationResult = Apollo.MutationResult; +export type UpdateGocardlessApiKeyMutationOptions = Apollo.BaseMutationOptions; +export const UpdateOrgaForLagoTaxManagementDocument = gql` + mutation updateOrgaForLagoTaxManagement($input: UpdateOrganizationInput!) { updateOrganization(input: $input) { id } } `; -export type UpdateOrgaForTagoTaxManagementMutationFn = Apollo.MutationFunction; +export type UpdateOrgaForLagoTaxManagementMutationFn = Apollo.MutationFunction; /** - * __useUpdateOrgaForTagoTaxManagementMutation__ + * __useUpdateOrgaForLagoTaxManagementMutation__ * - * To run a mutation, you first call `useUpdateOrgaForTagoTaxManagementMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useUpdateOrgaForTagoTaxManagementMutation` returns a tuple that includes: + * To run a mutation, you first call `useUpdateOrgaForLagoTaxManagementMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateOrgaForLagoTaxManagementMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [updateOrgaForTagoTaxManagementMutation, { data, loading, error }] = useUpdateOrgaForTagoTaxManagementMutation({ + * const [updateOrgaForLagoTaxManagementMutation, { data, loading, error }] = useUpdateOrgaForLagoTaxManagementMutation({ * variables: { * input: // value for 'input' * }, * }); */ -export function useUpdateOrgaForTagoTaxManagementMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useUpdateOrgaForLagoTaxManagementMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateOrgaForLagoTaxManagementDocument, options); + } +export type UpdateOrgaForLagoTaxManagementMutationHookResult = ReturnType; +export type UpdateOrgaForLagoTaxManagementMutationResult = Apollo.MutationResult; +export type UpdateOrgaForLagoTaxManagementMutationOptions = Apollo.BaseMutationOptions; +export const GetProviderByCodeForStripeDocument = gql` + query getProviderByCodeForStripe($code: String) { + paymentProvider(code: $code) { + ... on StripeProvider { + id + } + ... on GocardlessProvider { + id + } + ... on AdyenProvider { + id + } + } +} + `; + +/** + * __useGetProviderByCodeForStripeQuery__ + * + * To run a query within a React component, call `useGetProviderByCodeForStripeQuery` and pass it any options that fit your needs. + * When your component renders, `useGetProviderByCodeForStripeQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetProviderByCodeForStripeQuery({ + * variables: { + * code: // value for 'code' + * }, + * }); + */ +export function useGetProviderByCodeForStripeQuery(baseOptions?: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(UpdateOrgaForTagoTaxManagementDocument, options); + return Apollo.useQuery(GetProviderByCodeForStripeDocument, options); } -export type UpdateOrgaForTagoTaxManagementMutationHookResult = ReturnType; -export type UpdateOrgaForTagoTaxManagementMutationResult = Apollo.MutationResult; -export type UpdateOrgaForTagoTaxManagementMutationOptions = Apollo.BaseMutationOptions; +export function useGetProviderByCodeForStripeLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetProviderByCodeForStripeDocument, options); + } +export function useGetProviderByCodeForStripeSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(GetProviderByCodeForStripeDocument, options); + } +export type GetProviderByCodeForStripeQueryHookResult = ReturnType; +export type GetProviderByCodeForStripeLazyQueryHookResult = ReturnType; +export type GetProviderByCodeForStripeSuspenseQueryHookResult = ReturnType; +export type GetProviderByCodeForStripeQueryResult = Apollo.QueryResult; export const AddStripeApiKeyDocument = gql` mutation addStripeApiKey($input: AddStripePaymentProviderInput!) { addStripePaymentProvider(input: $input) { id - ...StripeIntegration + ...AddStripeProviderDialog + ...StripeIntegrationDetails } } - ${StripeIntegrationFragmentDoc}`; + ${AddStripeProviderDialogFragmentDoc} +${StripeIntegrationDetailsFragmentDoc}`; export type AddStripeApiKeyMutationFn = Apollo.MutationFunction; /** @@ -10076,39 +10778,108 @@ export function useAddStripeApiKeyMutation(baseOptions?: Apollo.MutationHookOpti export type AddStripeApiKeyMutationHookResult = ReturnType; export type AddStripeApiKeyMutationResult = Apollo.MutationResult; export type AddStripeApiKeyMutationOptions = Apollo.BaseMutationOptions; -export const DeleteAdyenDocument = gql` - mutation deleteAdyen($input: DestroyPaymentProviderInput!) { +export const UpdateStripeApiKeyDocument = gql` + mutation updateStripeApiKey($input: UpdateStripePaymentProviderInput!) { + updateStripePaymentProvider(input: $input) { + id + ...AddStripeProviderDialog + ...StripeIntegrationDetails + } +} + ${AddStripeProviderDialogFragmentDoc} +${StripeIntegrationDetailsFragmentDoc}`; +export type UpdateStripeApiKeyMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateStripeApiKeyMutation__ + * + * To run a mutation, you first call `useUpdateStripeApiKeyMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateStripeApiKeyMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateStripeApiKeyMutation, { data, loading, error }] = useUpdateStripeApiKeyMutation({ + * variables: { + * input: // value for 'input' + * }, + * }); + */ +export function useUpdateStripeApiKeyMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateStripeApiKeyDocument, options); + } +export type UpdateStripeApiKeyMutationHookResult = ReturnType; +export type UpdateStripeApiKeyMutationResult = Apollo.MutationResult; +export type UpdateStripeApiKeyMutationOptions = Apollo.BaseMutationOptions; +export const DeleteAdyenIntegrationDocument = gql` + mutation deleteAdyenIntegration($input: DestroyPaymentProviderInput!) { destroyPaymentProvider(input: $input) { id } } `; -export type DeleteAdyenMutationFn = Apollo.MutationFunction; +export type DeleteAdyenIntegrationMutationFn = Apollo.MutationFunction; /** - * __useDeleteAdyenMutation__ + * __useDeleteAdyenIntegrationMutation__ * - * To run a mutation, you first call `useDeleteAdyenMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useDeleteAdyenMutation` returns a tuple that includes: + * To run a mutation, you first call `useDeleteAdyenIntegrationMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteAdyenIntegrationMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [deleteAdyenMutation, { data, loading, error }] = useDeleteAdyenMutation({ + * const [deleteAdyenIntegrationMutation, { data, loading, error }] = useDeleteAdyenIntegrationMutation({ * variables: { * input: // value for 'input' * }, * }); */ -export function useDeleteAdyenMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useDeleteAdyenIntegrationMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(DeleteAdyenDocument, options); + return Apollo.useMutation(DeleteAdyenIntegrationDocument, options); } -export type DeleteAdyenMutationHookResult = ReturnType; -export type DeleteAdyenMutationResult = Apollo.MutationResult; -export type DeleteAdyenMutationOptions = Apollo.BaseMutationOptions; +export type DeleteAdyenIntegrationMutationHookResult = ReturnType; +export type DeleteAdyenIntegrationMutationResult = Apollo.MutationResult; +export type DeleteAdyenIntegrationMutationOptions = Apollo.BaseMutationOptions; +export const DeleteGocardlessDocument = gql` + mutation deleteGocardless($input: DestroyPaymentProviderInput!) { + destroyPaymentProvider(input: $input) { + id + } +} + `; +export type DeleteGocardlessMutationFn = Apollo.MutationFunction; + +/** + * __useDeleteGocardlessMutation__ + * + * To run a mutation, you first call `useDeleteGocardlessMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteGocardlessMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [deleteGocardlessMutation, { data, loading, error }] = useDeleteGocardlessMutation({ + * variables: { + * input: // value for 'input' + * }, + * }); + */ +export function useDeleteGocardlessMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(DeleteGocardlessDocument, options); + } +export type DeleteGocardlessMutationHookResult = ReturnType; +export type DeleteGocardlessMutationResult = Apollo.MutationResult; +export type DeleteGocardlessMutationOptions = Apollo.BaseMutationOptions; export const DeleteStripeDocument = gql` mutation deleteStripe($input: DestroyPaymentProviderInput!) { destroyPaymentProvider(input: $input) { @@ -11145,6 +11916,65 @@ export function useUpdateCustomerMutation(baseOptions?: Apollo.MutationHookOptio export type UpdateCustomerMutationHookResult = ReturnType; export type UpdateCustomerMutationResult = Apollo.MutationResult; export type UpdateCustomerMutationOptions = Apollo.BaseMutationOptions; +export const IntegrationsListForCustomerCreateEditDocument = gql` + query integrationsListForCustomerCreateEdit($limit: Int) { + paymentProviders(limit: $limit) { + collection { + ... on StripeProvider { + __typename + id + name + code + } + ... on GocardlessProvider { + __typename + id + name + code + } + ... on AdyenProvider { + __typename + id + name + code + } + } + } +} + `; + +/** + * __useIntegrationsListForCustomerCreateEditQuery__ + * + * To run a query within a React component, call `useIntegrationsListForCustomerCreateEditQuery` and pass it any options that fit your needs. + * When your component renders, `useIntegrationsListForCustomerCreateEditQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useIntegrationsListForCustomerCreateEditQuery({ + * variables: { + * limit: // value for 'limit' + * }, + * }); + */ +export function useIntegrationsListForCustomerCreateEditQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(IntegrationsListForCustomerCreateEditDocument, options); + } +export function useIntegrationsListForCustomerCreateEditLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(IntegrationsListForCustomerCreateEditDocument, options); + } +export function useIntegrationsListForCustomerCreateEditSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(IntegrationsListForCustomerCreateEditDocument, options); + } +export type IntegrationsListForCustomerCreateEditQueryHookResult = ReturnType; +export type IntegrationsListForCustomerCreateEditLazyQueryHookResult = ReturnType; +export type IntegrationsListForCustomerCreateEditSuspenseQueryHookResult = ReturnType; +export type IntegrationsListForCustomerCreateEditQueryResult = Apollo.QueryResult; export const GetSingleTaxDocument = gql` query getSingleTax($id: ID!) { tax(id: $id) { @@ -12102,6 +12932,7 @@ export const GetCreditNoteDocument = gql` } items { amountCents + amountCurrency fee { id amountCents @@ -13430,148 +14261,274 @@ export type GetWebhookListQueryHookResult = ReturnType; export type GetWebhookListSuspenseQueryHookResult = ReturnType; export type GetWebhookListQueryResult = Apollo.QueryResult; -export const AdyenIntegrationsSettingDocument = gql` - query AdyenIntegrationsSetting { - organization { - id - adyenPaymentProvider { +export const GetAdyenIntegrationsDetailsDocument = gql` + query getAdyenIntegrationsDetails($id: ID!, $limit: Int, $type: ProviderTypeEnum) { + paymentProvider(id: $id) { + ... on AdyenProvider { id - successRedirectUrl - ...AdyenIntegration + ...AdyenIntegrationDetails + ...DeleteAdyenIntegrationDialog + ...AddAdyenProviderDialog ...AdyenForCreateAndEditSuccessRedirectUrl } } + paymentProviders(limit: $limit, type: $type) { + collection { + ... on AdyenProvider { + id + } + } + } } - ${AdyenIntegrationFragmentDoc} + ${AdyenIntegrationDetailsFragmentDoc} +${DeleteAdyenIntegrationDialogFragmentDoc} +${AddAdyenProviderDialogFragmentDoc} ${AdyenForCreateAndEditSuccessRedirectUrlFragmentDoc}`; /** - * __useAdyenIntegrationsSettingQuery__ + * __useGetAdyenIntegrationsDetailsQuery__ * - * To run a query within a React component, call `useAdyenIntegrationsSettingQuery` and pass it any options that fit your needs. - * When your component renders, `useAdyenIntegrationsSettingQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useGetAdyenIntegrationsDetailsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetAdyenIntegrationsDetailsQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useAdyenIntegrationsSettingQuery({ + * const { data, loading, error } = useGetAdyenIntegrationsDetailsQuery({ * variables: { + * id: // value for 'id' + * limit: // value for 'limit' + * type: // value for 'type' * }, * }); */ -export function useAdyenIntegrationsSettingQuery(baseOptions?: Apollo.QueryHookOptions) { +export function useGetAdyenIntegrationsDetailsQuery(baseOptions: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(AdyenIntegrationsSettingDocument, options); + return Apollo.useQuery(GetAdyenIntegrationsDetailsDocument, options); } -export function useAdyenIntegrationsSettingLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { +export function useGetAdyenIntegrationsDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(AdyenIntegrationsSettingDocument, options); + return Apollo.useLazyQuery(GetAdyenIntegrationsDetailsDocument, options); } -export function useAdyenIntegrationsSettingSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { +export function useGetAdyenIntegrationsDetailsSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useSuspenseQuery(AdyenIntegrationsSettingDocument, options); + return Apollo.useSuspenseQuery(GetAdyenIntegrationsDetailsDocument, options); } -export type AdyenIntegrationsSettingQueryHookResult = ReturnType; -export type AdyenIntegrationsSettingLazyQueryHookResult = ReturnType; -export type AdyenIntegrationsSettingSuspenseQueryHookResult = ReturnType; -export type AdyenIntegrationsSettingQueryResult = Apollo.QueryResult; -export const GocardlessIntegrationsSettingDocument = gql` - query gocardlessIntegrationsSetting { - organization { - id - gocardlessPaymentProvider { +export type GetAdyenIntegrationsDetailsQueryHookResult = ReturnType; +export type GetAdyenIntegrationsDetailsLazyQueryHookResult = ReturnType; +export type GetAdyenIntegrationsDetailsSuspenseQueryHookResult = ReturnType; +export type GetAdyenIntegrationsDetailsQueryResult = Apollo.QueryResult; +export const GetAdyenIntegrationsListDocument = gql` + query getAdyenIntegrationsList($limit: Int, $type: ProviderTypeEnum) { + paymentProviders(limit: $limit, type: $type) { + collection { + ... on AdyenProvider { + id + ...AdyenIntegrations + ...AddAdyenProviderDialog + ...DeleteAdyenIntegrationDialog + } + } + } +} + ${AdyenIntegrationsFragmentDoc} +${AddAdyenProviderDialogFragmentDoc} +${DeleteAdyenIntegrationDialogFragmentDoc}`; + +/** + * __useGetAdyenIntegrationsListQuery__ + * + * To run a query within a React component, call `useGetAdyenIntegrationsListQuery` and pass it any options that fit your needs. + * When your component renders, `useGetAdyenIntegrationsListQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetAdyenIntegrationsListQuery({ + * variables: { + * limit: // value for 'limit' + * type: // value for 'type' + * }, + * }); + */ +export function useGetAdyenIntegrationsListQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetAdyenIntegrationsListDocument, options); + } +export function useGetAdyenIntegrationsListLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetAdyenIntegrationsListDocument, options); + } +export function useGetAdyenIntegrationsListSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(GetAdyenIntegrationsListDocument, options); + } +export type GetAdyenIntegrationsListQueryHookResult = ReturnType; +export type GetAdyenIntegrationsListLazyQueryHookResult = ReturnType; +export type GetAdyenIntegrationsListSuspenseQueryHookResult = ReturnType; +export type GetAdyenIntegrationsListQueryResult = Apollo.QueryResult; +export const GetGocardlessIntegrationsDetailsDocument = gql` + query getGocardlessIntegrationsDetails($id: ID!, $limit: Int, $type: ProviderTypeEnum) { + paymentProvider(id: $id) { + ... on GocardlessProvider { id - hasAccessToken - webhookSecret - successRedirectUrl - ...gocardlessForCreateAndEditSuccessRedirectUrl + ...GocardlessIntegrationDetails + ...DeleteGocardlessIntegrationDialog + ...AddGocardlessProviderDialog + } + } + paymentProviders(limit: $limit, type: $type) { + collection { + ... on GocardlessProvider { + id + } } } } - ${GocardlessForCreateAndEditSuccessRedirectUrlFragmentDoc}`; + ${GocardlessIntegrationDetailsFragmentDoc} +${DeleteGocardlessIntegrationDialogFragmentDoc} +${AddGocardlessProviderDialogFragmentDoc}`; /** - * __useGocardlessIntegrationsSettingQuery__ + * __useGetGocardlessIntegrationsDetailsQuery__ * - * To run a query within a React component, call `useGocardlessIntegrationsSettingQuery` and pass it any options that fit your needs. - * When your component renders, `useGocardlessIntegrationsSettingQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useGetGocardlessIntegrationsDetailsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetGocardlessIntegrationsDetailsQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useGocardlessIntegrationsSettingQuery({ + * const { data, loading, error } = useGetGocardlessIntegrationsDetailsQuery({ * variables: { + * id: // value for 'id' + * limit: // value for 'limit' + * type: // value for 'type' * }, * }); */ -export function useGocardlessIntegrationsSettingQuery(baseOptions?: Apollo.QueryHookOptions) { +export function useGetGocardlessIntegrationsDetailsQuery(baseOptions: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(GocardlessIntegrationsSettingDocument, options); + return Apollo.useQuery(GetGocardlessIntegrationsDetailsDocument, options); } -export function useGocardlessIntegrationsSettingLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { +export function useGetGocardlessIntegrationsDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(GocardlessIntegrationsSettingDocument, options); + return Apollo.useLazyQuery(GetGocardlessIntegrationsDetailsDocument, options); } -export function useGocardlessIntegrationsSettingSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { +export function useGetGocardlessIntegrationsDetailsSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useSuspenseQuery(GocardlessIntegrationsSettingDocument, options); + return Apollo.useSuspenseQuery(GetGocardlessIntegrationsDetailsDocument, options); } -export type GocardlessIntegrationsSettingQueryHookResult = ReturnType; -export type GocardlessIntegrationsSettingLazyQueryHookResult = ReturnType; -export type GocardlessIntegrationsSettingSuspenseQueryHookResult = ReturnType; -export type GocardlessIntegrationsSettingQueryResult = Apollo.QueryResult; -export const AddGocardlessPaymentProviderDocument = gql` - mutation addGocardlessPaymentProvider($input: AddGocardlessPaymentProviderInput!) { +export type GetGocardlessIntegrationsDetailsQueryHookResult = ReturnType; +export type GetGocardlessIntegrationsDetailsLazyQueryHookResult = ReturnType; +export type GetGocardlessIntegrationsDetailsSuspenseQueryHookResult = ReturnType; +export type GetGocardlessIntegrationsDetailsQueryResult = Apollo.QueryResult; +export const AddGocardlessApiKeyDocument = gql` + mutation addGocardlessApiKey($input: AddGocardlessPaymentProviderInput!) { addGocardlessPaymentProvider(input: $input) { id - hasAccessToken - webhookSecret - successRedirectUrl + ...AddGocardlessProviderDialog + ...GocardlessIntegrationOauthCallback } } - `; -export type AddGocardlessPaymentProviderMutationFn = Apollo.MutationFunction; + ${AddGocardlessProviderDialogFragmentDoc} +${GocardlessIntegrationOauthCallbackFragmentDoc}`; +export type AddGocardlessApiKeyMutationFn = Apollo.MutationFunction; /** - * __useAddGocardlessPaymentProviderMutation__ + * __useAddGocardlessApiKeyMutation__ * - * To run a mutation, you first call `useAddGocardlessPaymentProviderMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useAddGocardlessPaymentProviderMutation` returns a tuple that includes: + * To run a mutation, you first call `useAddGocardlessApiKeyMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useAddGocardlessApiKeyMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [addGocardlessPaymentProviderMutation, { data, loading, error }] = useAddGocardlessPaymentProviderMutation({ + * const [addGocardlessApiKeyMutation, { data, loading, error }] = useAddGocardlessApiKeyMutation({ * variables: { * input: // value for 'input' * }, * }); */ -export function useAddGocardlessPaymentProviderMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useAddGocardlessApiKeyMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(AddGocardlessPaymentProviderDocument, options); + return Apollo.useMutation(AddGocardlessApiKeyDocument, options); } -export type AddGocardlessPaymentProviderMutationHookResult = ReturnType; -export type AddGocardlessPaymentProviderMutationResult = Apollo.MutationResult; -export type AddGocardlessPaymentProviderMutationOptions = Apollo.BaseMutationOptions; +export type AddGocardlessApiKeyMutationHookResult = ReturnType; +export type AddGocardlessApiKeyMutationResult = Apollo.MutationResult; +export type AddGocardlessApiKeyMutationOptions = Apollo.BaseMutationOptions; +export const GetGocardlessIntegrationsListDocument = gql` + query getGocardlessIntegrationsList($limit: Int, $type: ProviderTypeEnum) { + paymentProviders(limit: $limit, type: $type) { + collection { + ... on GocardlessProvider { + id + ...GocardlessIntegrations + ...AddGocardlessProviderDialog + ...DeleteGocardlessIntegrationDialog + } + } + } +} + ${GocardlessIntegrationsFragmentDoc} +${AddGocardlessProviderDialogFragmentDoc} +${DeleteGocardlessIntegrationDialogFragmentDoc}`; + +/** + * __useGetGocardlessIntegrationsListQuery__ + * + * To run a query within a React component, call `useGetGocardlessIntegrationsListQuery` and pass it any options that fit your needs. + * When your component renders, `useGetGocardlessIntegrationsListQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetGocardlessIntegrationsListQuery({ + * variables: { + * limit: // value for 'limit' + * type: // value for 'type' + * }, + * }); + */ +export function useGetGocardlessIntegrationsListQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetGocardlessIntegrationsListDocument, options); + } +export function useGetGocardlessIntegrationsListLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetGocardlessIntegrationsListDocument, options); + } +export function useGetGocardlessIntegrationsListSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(GetGocardlessIntegrationsListDocument, options); + } +export type GetGocardlessIntegrationsListQueryHookResult = ReturnType; +export type GetGocardlessIntegrationsListLazyQueryHookResult = ReturnType; +export type GetGocardlessIntegrationsListSuspenseQueryHookResult = ReturnType; +export type GetGocardlessIntegrationsListQueryResult = Apollo.QueryResult; export const IntegrationsSettingDocument = gql` - query integrationsSetting { + query integrationsSetting($limit: Int) { organization { id euTaxManagement country - stripePaymentProvider { - id - } - gocardlessPaymentProvider { - id - } - adyenPaymentProvider { - id + } + paymentProviders(limit: $limit) { + collection { + ... on StripeProvider { + id + } + ... on GocardlessProvider { + id + } + ... on AdyenProvider { + id + } } } } @@ -13589,6 +14546,7 @@ export const IntegrationsSettingDocument = gql` * @example * const { data, loading, error } = useIntegrationsSettingQuery({ * variables: { + * limit: // value for 'limit' * }, * }); */ @@ -13932,81 +14890,114 @@ export type GetOrganizationInformationsQueryHookResult = ReturnType; export type GetOrganizationInformationsSuspenseQueryHookResult = ReturnType; export type GetOrganizationInformationsQueryResult = Apollo.QueryResult; -export const StripeIntegrationsSettingDocument = gql` - query stripeIntegrationsSetting { - organization { - id - stripePaymentProvider { - ...StripeIntegration +export const GetStripeIntegrationsDetailsDocument = gql` + query getStripeIntegrationsDetails($id: ID!, $limit: Int, $type: ProviderTypeEnum) { + paymentProvider(id: $id) { + ... on StripeProvider { + id + ...StripeIntegrationDetails + ...DeleteStripeIntegrationDialog + ...AddStripeProviderDialog + ...StripeForCreateAndEditSuccessRedirectUrl + } + } + paymentProviders(limit: $limit, type: $type) { + collection { + ... on StripeProvider { + id + } } } } - ${StripeIntegrationFragmentDoc}`; + ${StripeIntegrationDetailsFragmentDoc} +${DeleteStripeIntegrationDialogFragmentDoc} +${AddStripeProviderDialogFragmentDoc} +${StripeForCreateAndEditSuccessRedirectUrlFragmentDoc}`; /** - * __useStripeIntegrationsSettingQuery__ + * __useGetStripeIntegrationsDetailsQuery__ * - * To run a query within a React component, call `useStripeIntegrationsSettingQuery` and pass it any options that fit your needs. - * When your component renders, `useStripeIntegrationsSettingQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useGetStripeIntegrationsDetailsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetStripeIntegrationsDetailsQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useStripeIntegrationsSettingQuery({ + * const { data, loading, error } = useGetStripeIntegrationsDetailsQuery({ * variables: { + * id: // value for 'id' + * limit: // value for 'limit' + * type: // value for 'type' * }, * }); */ -export function useStripeIntegrationsSettingQuery(baseOptions?: Apollo.QueryHookOptions) { +export function useGetStripeIntegrationsDetailsQuery(baseOptions: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(StripeIntegrationsSettingDocument, options); + return Apollo.useQuery(GetStripeIntegrationsDetailsDocument, options); } -export function useStripeIntegrationsSettingLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { +export function useGetStripeIntegrationsDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(StripeIntegrationsSettingDocument, options); + return Apollo.useLazyQuery(GetStripeIntegrationsDetailsDocument, options); } -export function useStripeIntegrationsSettingSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { +export function useGetStripeIntegrationsDetailsSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useSuspenseQuery(StripeIntegrationsSettingDocument, options); + return Apollo.useSuspenseQuery(GetStripeIntegrationsDetailsDocument, options); } -export type StripeIntegrationsSettingQueryHookResult = ReturnType; -export type StripeIntegrationsSettingLazyQueryHookResult = ReturnType; -export type StripeIntegrationsSettingSuspenseQueryHookResult = ReturnType; -export type StripeIntegrationsSettingQueryResult = Apollo.QueryResult; -export const UpdateStripeIntegrationDocument = gql` - mutation updateStripeIntegration($input: AddStripePaymentProviderInput!) { - addStripePaymentProvider(input: $input) { - ...StripeIntegration +export type GetStripeIntegrationsDetailsQueryHookResult = ReturnType; +export type GetStripeIntegrationsDetailsLazyQueryHookResult = ReturnType; +export type GetStripeIntegrationsDetailsSuspenseQueryHookResult = ReturnType; +export type GetStripeIntegrationsDetailsQueryResult = Apollo.QueryResult; +export const GetStripeIntegrationsListDocument = gql` + query getStripeIntegrationsList($limit: Int, $type: ProviderTypeEnum) { + paymentProviders(limit: $limit, type: $type) { + collection { + ... on StripeProvider { + id + ...StripeIntegrations + ...AddStripeProviderDialog + ...DeleteStripeIntegrationDialog + } + } } } - ${StripeIntegrationFragmentDoc}`; -export type UpdateStripeIntegrationMutationFn = Apollo.MutationFunction; + ${StripeIntegrationsFragmentDoc} +${AddStripeProviderDialogFragmentDoc} +${DeleteStripeIntegrationDialogFragmentDoc}`; /** - * __useUpdateStripeIntegrationMutation__ + * __useGetStripeIntegrationsListQuery__ * - * To run a mutation, you first call `useUpdateStripeIntegrationMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useUpdateStripeIntegrationMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution + * To run a query within a React component, call `useGetStripeIntegrationsListQuery` and pass it any options that fit your needs. + * When your component renders, `useGetStripeIntegrationsListQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const [updateStripeIntegrationMutation, { data, loading, error }] = useUpdateStripeIntegrationMutation({ + * const { data, loading, error } = useGetStripeIntegrationsListQuery({ * variables: { - * input: // value for 'input' + * limit: // value for 'limit' + * type: // value for 'type' * }, * }); */ -export function useUpdateStripeIntegrationMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useGetStripeIntegrationsListQuery(baseOptions?: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(UpdateStripeIntegrationDocument, options); + return Apollo.useQuery(GetStripeIntegrationsListDocument, options); } -export type UpdateStripeIntegrationMutationHookResult = ReturnType; -export type UpdateStripeIntegrationMutationResult = Apollo.MutationResult; -export type UpdateStripeIntegrationMutationOptions = Apollo.BaseMutationOptions; +export function useGetStripeIntegrationsListLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetStripeIntegrationsListDocument, options); + } +export function useGetStripeIntegrationsListSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(GetStripeIntegrationsListDocument, options); + } +export type GetStripeIntegrationsListQueryHookResult = ReturnType; +export type GetStripeIntegrationsListLazyQueryHookResult = ReturnType; +export type GetStripeIntegrationsListSuspenseQueryHookResult = ReturnType; +export type GetStripeIntegrationsListQueryResult = Apollo.QueryResult; export const GetTaxesDocument = gql` query getTaxes($limit: Int, $page: Int) { taxes(limit: $limit, page: $page, order: "name") { diff --git a/src/hooks/customer/useAddSubscription.tsx b/src/hooks/customer/useAddSubscription.tsx index 9efb610c1..e9ced0509 100644 --- a/src/hooks/customer/useAddSubscription.tsx +++ b/src/hooks/customer/useAddSubscription.tsx @@ -233,7 +233,9 @@ export const useAddSubscription: UseAddSubscription = ({ ? DateTime.fromISO(existingSubscription?.startedAt) .toUTC() .toISO() - : undefined, + : subsDate + ? DateTime.fromISO(subsDate).toUTC().toISO() + : undefined, endingAt: !!subEndDate ? DateTime.fromISO(subEndDate).toUTC().toISO() : null, name: name || undefined, planOverrides: hasPlanBeingChangedFromInitial diff --git a/src/hooks/useCreateEditCustomer.ts b/src/hooks/useCreateEditCustomer.ts index 771d25741..bb6a8fd50 100644 --- a/src/hooks/useCreateEditCustomer.ts +++ b/src/hooks/useCreateEditCustomer.ts @@ -11,9 +11,11 @@ import { CustomerItemFragmentDoc, LagoApiError, ProviderPaymentMethodsEnum, + ProviderTypeEnum, UpdateCustomerInput, UpdateCustomerMutation, useCreateCustomerMutation, + useIntegrationsListForCustomerCreateEditQuery, useUpdateCustomerMutation, } from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' @@ -41,6 +43,7 @@ gql` timezone zipcode url + paymentProviderCode providerCustomer { id providerCustomerId @@ -69,10 +72,51 @@ gql` } } + query integrationsListForCustomerCreateEdit($limit: Int) { + paymentProviders(limit: $limit) { + collection { + ... on StripeProvider { + __typename + id + name + code + } + + ... on GocardlessProvider { + __typename + id + name + code + } + + ... on AdyenProvider { + __typename + id + name + code + } + } + } + } + ${CustomerItemFragmentDoc} ` +type TPaymentProviderForCustomer = { + __typename: string + type: ProviderTypeEnum + id: string + name: string + code: string +} + +type TPaymentProviderForCustomerGroupByTypename = + | Record + | undefined + | null + type UseCreateEditCustomer = (props: { customer?: AddCustomerDrawerFragment | null }) => { + paymentProvidersList: TPaymentProviderForCustomerGroupByTypename isEdition: boolean onSave: ( values: CreateCustomerInput | UpdateCustomerInput, @@ -85,6 +129,23 @@ type UseCreateEditCustomer = (props: { customer?: AddCustomerDrawerFragment | nu export const useCreateEditCustomer: UseCreateEditCustomer = ({ customer }) => { const { translate } = useInternationalization() const navigate = useNavigate() + const { data: providersData } = useIntegrationsListForCustomerCreateEditQuery({ + variables: { limit: 100 }, + }) + // group payment providers by __typeName + const paymentProvidersList = providersData?.paymentProviders?.collection.reduce< + Record | undefined | null + >((acc, curr) => { + if (!acc) return + const type = curr.__typename.toLowerCase().replace('provider', '') as ProviderTypeEnum + + if (!acc[type]) { + acc[type] = [] + } + acc[type].push({ ...curr, type }) + return acc + }, {} as TPaymentProviderForCustomerGroupByTypename) + const [create] = useCreateCustomerMutation({ context: { silentErrorCodes: [LagoApiError.UnprocessableEntity] }, onCompleted({ createCustomer }) { @@ -118,6 +179,7 @@ export const useCreateEditCustomer: UseCreateEditCustomer = ({ customer }) => { }) return { + paymentProvidersList, isEdition: !!customer, onSave: !!customer ? async ({ providerCustomer, paymentProvider, ...values }) => diff --git a/src/layouts/SideNavLayout.tsx b/src/layouts/SideNavLayout.tsx index 7691af3df..3091af688 100644 --- a/src/layouts/SideNavLayout.tsx +++ b/src/layouts/SideNavLayout.tsx @@ -147,36 +147,41 @@ const SideNav = () => { {currentUser?.email} - {currentUser?.organizations && ( + {!!currentUser?.organizations?.length && ( - {currentUser?.organizations?.map(({ id, name, logoUrl }) => ( - - ))} + {Object.values(currentUser?.organizations) + ?.sort( + (a, b) => + a.name.toLowerCase()?.localeCompare(b.name.toLowerCase() ?? '') ?? 0, + ) + ?.map(({ id, name, logoUrl }) => ( + + ))} )} diff --git a/src/pages/CreateSubscription.tsx b/src/pages/CreateSubscription.tsx index b4c7ea59b..e79332b37 100644 --- a/src/pages/CreateSubscription.tsx +++ b/src/pages/CreateSubscription.tsx @@ -820,7 +820,7 @@ const FormPlanWrapper = styled.div` const InlineFields = styled.div` display: flex; gap: ${theme.spacing(6)}; - align-items: flex-end; + align-items: flex-start; > * { flex: 1; diff --git a/src/pages/CreditNoteDetails.tsx b/src/pages/CreditNoteDetails.tsx index 24a70370a..f2265531e 100644 --- a/src/pages/CreditNoteDetails.tsx +++ b/src/pages/CreditNoteDetails.tsx @@ -44,7 +44,7 @@ import { useInternationalization } from '~/hooks/core/useInternationalization' import { useLocationHistory } from '~/hooks/core/useLocationHistory' import { CustomerInvoiceDetailsTabsOptionsEnum } from '~/layouts/CustomerInvoiceDetails' import ErrorImage from '~/public/images/maneki/error.svg' -import { MenuPopper, NAV_HEIGHT, PageHeader, theme } from '~/styles' +import { MenuPopper, PageHeader, theme } from '~/styles' import { SectionHeader } from '~/styles/customer' import { CustomerDetailsTabsOptions } from './CustomerDetails' @@ -85,6 +85,7 @@ gql` } items { amountCents + amountCurrency fee { id amountCents @@ -402,7 +403,7 @@ const CreditNoteDetails = () => { ) : ( -
+ {creditNote?.customer?.name && ( <> @@ -460,8 +461,8 @@ const CreditNoteDetails = () => { )} -
-
+ + {!isRefunded && ( @@ -499,7 +500,7 @@ const CreditNoteDetails = () => { /> -
+
)} @@ -521,17 +522,17 @@ const CreditNoteDetails = () => { - + {invoiceDisplayName} - + {translate('text_636bedf292786b19d3398f06')} - + {translate('text_637655cb50f04bf1c8379d12')} @@ -552,7 +553,7 @@ const CreditNoteDetails = () => { - + {groupDimension === 0 || !!isTrueUp ? ( <> {item?.fee?.feeType === FeeTypesEnum.AddOn @@ -919,7 +920,6 @@ const InfoSection = styled.section` const InfoLine = styled.div` display: flex; align-items: flex-start; - margin-bottom: ${theme.spacing(2)}; > div:first-child { min-width: 140px; @@ -939,6 +939,12 @@ const InfoLine = styled.div` } ` +const InfoLineWrapper = styled.div` + > *:not(:last-child) { + margin-bottom: ${theme.spacing(2)}; + } +` + const TableSection = styled.section` .main-table:not(:first-child) { margin-top: ${theme.spacing(10)}; @@ -953,9 +959,11 @@ const TableSection = styled.section` > tbody > tr > td { overflow: hidden; line-break: anywhere; + text-align: right; &:nth-child(1) { width: 70%; + text-align: left; } &:nth-child(2) { width: 10%; @@ -963,65 +971,46 @@ const TableSection = styled.section` &:nth-child(3) { width: 20%; } - } - - > tfoot > tr > td { - &:nth-child(1) { - width: 50%; - } - &:nth-child(2) { - width: 35%; - } - &:nth-child(3) { - width: 15%; - } - } - > tfoot > tr > td { - &:nth-child(2) { - text-align: left; + &:not(:last-child) { + padding-right: ${theme.spacing(3)}; } } - th:not(:last-child), - td:not(:last-child) { - padding-right: ${theme.spacing(3)}; + > thead > tr > th { + position: sticky; + top: 72px; + background-color: ${theme.palette.common.white}; + z-index: 1; + padding: ${theme.spacing(8)} 0 ${theme.spacing(3)} 0; + box-sizing: border-box; + box-shadow: ${theme.shadows[7]}; } - > thead > tr > th, > tbody > tr > td { - text-align: right; - - &:first-child { - text-align: left; - } + vertical-align: top; + min-height: 44px; + padding: ${theme.spacing(3)} 0; + box-shadow: ${theme.shadows[7]}; } > tfoot > tr > td { text-align: right; padding: ${theme.spacing(3)} 0; - } - > tfoot > tr > td { - &:nth-child(2), + &:nth-child(1) { + width: 50%; + } + &:nth-child(2) { + width: 35%; + box-shadow: ${theme.shadows[7]}; + text-align: left; + } &:nth-child(3) { + width: 15%; box-shadow: ${theme.shadows[7]}; } } - - > thead > tr > th { - height: ${NAV_HEIGHT}px; - padding: ${theme.spacing(8)} 0 ${theme.spacing(3)} 0; - box-sizing: border-box; - box-shadow: ${theme.shadows[7]}; - } - - > tbody > tr > td { - vertical-align: top; - min-height: 44px; - padding: ${theme.spacing(3)} 0; - box-shadow: ${theme.shadows[7]}; - } } ` diff --git a/src/pages/CustomerDetails.tsx b/src/pages/CustomerDetails.tsx index adea91043..31aa97aaa 100644 --- a/src/pages/CustomerDetails.tsx +++ b/src/pages/CustomerDetails.tsx @@ -462,6 +462,9 @@ const HeaderInlineBreadcrumbBlock = styled.div` /* Prevent long name to not overflow in header */ overflow: hidden; + /* As overflow is hidden, prevent focus ring to be cropped */ + padding: 4px; + margin: -4px; ` const HeaderInlineActionsBlock = styled.div` @@ -502,7 +505,7 @@ const Infos = styled.div` width: 320px; margin-right: ${theme.spacing(8)}; - @media (max-width: 1024px) { + ${theme.breakpoints.down('lg')} { flex: 1; width: inherit; margin-right: 0; @@ -513,7 +516,7 @@ const Infos = styled.div` min-width: 0; } - @media (max-width: 1024px) { + ${theme.breakpoints.down('lg')} { flex-direction: column; } ` diff --git a/src/pages/CustomerDraftInvoicesList.tsx b/src/pages/CustomerDraftInvoicesList.tsx index 419f4e2bf..bfac3b997 100644 --- a/src/pages/CustomerDraftInvoicesList.tsx +++ b/src/pages/CustomerDraftInvoicesList.tsx @@ -119,7 +119,7 @@ const CustomerDraftInvoicesList = () => { {translate('text_638f74bb4d41e3f1d020164b', { - count: customerData?.customerInvoices?.metadata.totalCount, + count: customerData?.customerInvoices?.metadata?.totalCount, })}
diff --git a/src/pages/InvoiceOverview.tsx b/src/pages/InvoiceOverview.tsx index d94ca8d21..e614a9621 100644 --- a/src/pages/InvoiceOverview.tsx +++ b/src/pages/InvoiceOverview.tsx @@ -5,13 +5,16 @@ import styled from 'styled-components' import { Alert, Button, Skeleton } from '~/components/designSystem' import { GenericPlaceholder } from '~/components/GenericPlaceholder' +import { + InvoiceDetailsTable, + InvoiceWrapper, +} from '~/components/invoices/details/InvoiceDetailsTable' import { FinalizeInvoiceDialog, FinalizeInvoiceDialogRef, } from '~/components/invoices/FinalizeInvoiceDialog' import { InvoiceCreditNotesTable } from '~/components/invoices/InvoiceCreditNotesTable' import { InvoiceCustomerInfos } from '~/components/invoices/InvoiceCustomerInfos' -import { InvoiceDetailsTable } from '~/components/invoices/InvoiceDetailsTable' import { Metadatas } from '~/components/invoices/Metadatas' import formatCreditNotesItems from '~/core/formats/formatCreditNotesItems' import { formatDateToTZ } from '~/core/timezone' @@ -132,14 +135,54 @@ const InvoiceOverview = memo( <> {loading ? ( <> - {[1, 2, 3, 4].map((i) => ( - - - - - - - ))} + + {[1, 2, 3, 4, 5].map((i) => ( + + + + + + + ))} + + + + + {[1, 2, 3, 4, 5].map((k) => ( + + + + + + + + ))} + + + {[1, 2, 3].map((i) => ( + + + + + + ))} + +
+ + + + + + + + + +
+ + + +
+
) : ( <> @@ -157,11 +200,7 @@ const InvoiceOverview = memo( )} - + {!!formatedCreditNotes?.length && invoice?.status !== InvoiceStatusTypeEnum.Draft && !loadingRefreshInvoice && ( @@ -207,4 +246,25 @@ const DraftAlertWrapper = styled.div` padding-top: ${theme.spacing(3)}; ` +const LoadingTR = styled.tr` + > td { + box-sizing: border-box; + padding: ${theme.spacing(3)} 0; + } +` + +const RightSkeleton = styled(Skeleton)` + float: right; +` + +const LoadingInfosWrapper = styled.div` + margin-bottom: ${theme.spacing(7)}; +` + +const LoadingInvoiceWrapper = styled(InvoiceWrapper)` + > table > tbody > tr > td { + padding: ${theme.spacing(5)} 0; + } +` + export default InvoiceOverview diff --git a/src/pages/settings/AdyenIntegration.tsx b/src/pages/settings/AdyenIntegrationDetails.tsx similarity index 69% rename from src/pages/settings/AdyenIntegration.tsx rename to src/pages/settings/AdyenIntegrationDetails.tsx index b93a43679..9a1b78c3f 100644 --- a/src/pages/settings/AdyenIntegration.tsx +++ b/src/pages/settings/AdyenIntegrationDetails.tsx @@ -1,5 +1,6 @@ import { gql } from '@apollo/client' import { useRef } from 'react' +import { useNavigate, useParams } from 'react-router-dom' import styled from 'styled-components' import { @@ -25,53 +26,88 @@ import { DeleteAdyenIntegrationDialog, DeleteAdyenIntegrationDialogRef, } from '~/components/settings/integrations/DeleteAdyenIntegrationDialog' -import { INTEGRATIONS_ROUTE } from '~/core/router' +import { ADYEN_INTEGRATION_ROUTE, INTEGRATIONS_ROUTE } from '~/core/router' import { + AddAdyenProviderDialogFragmentDoc, AdyenForCreateAndEditSuccessRedirectUrlFragmentDoc, - useAdyenIntegrationsSettingQuery, + AdyenIntegrationDetailsFragment, + DeleteAdyenIntegrationDialogFragmentDoc, + ProviderTypeEnum, + useGetAdyenIntegrationsDetailsQuery, } from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' import Adyen from '~/public/images/adyen.svg' import { MenuPopper, NAV_HEIGHT, PageHeader, PopperOpener, theme } from '~/styles' +const PROVIDER_CONNECTION_LIMIT = 2 + gql` - fragment AdyenIntegration on AdyenProvider { + fragment AdyenIntegrationDetails on AdyenProvider { id apiKey + code hmacKey livePrefix merchantAccount + successRedirectUrl + name } - query AdyenIntegrationsSetting { - organization { - id - adyenPaymentProvider { + query getAdyenIntegrationsDetails($id: ID!, $limit: Int, $type: ProviderTypeEnum) { + paymentProvider(id: $id) { + ... on AdyenProvider { id - successRedirectUrl - ...AdyenIntegration + ...AdyenIntegrationDetails + ...DeleteAdyenIntegrationDialog + ...AddAdyenProviderDialog ...AdyenForCreateAndEditSuccessRedirectUrl } } + + paymentProviders(limit: $limit, type: $type) { + collection { + ... on AdyenProvider { + id + } + } + } } ${AdyenForCreateAndEditSuccessRedirectUrlFragmentDoc} + ${DeleteAdyenIntegrationDialogFragmentDoc} + ${AddAdyenProviderDialogFragmentDoc} ` -const AdyenIntegration = () => { +const AdyenIntegrationDetails = () => { + const navigate = useNavigate() + const { integrationId } = useParams() const addAdyenDialogRef = useRef(null) const deleteDialogRef = useRef(null) const successRedirectUrlDialogRef = useRef(null) const { translate } = useInternationalization() - const { data, loading } = useAdyenIntegrationsSettingQuery() - const adyenPaymentProvider = data?.organization?.adyenPaymentProvider + const { data, loading } = useGetAdyenIntegrationsDetailsQuery({ + variables: { + id: integrationId as string, + limit: PROVIDER_CONNECTION_LIMIT, + type: ProviderTypeEnum.Adyen, + }, + skip: !integrationId, + }) + const adyenPaymentProvider = data?.paymentProvider as AdyenIntegrationDetailsFragment + const deleteDialogCallback = () => { + if (data?.paymentProviders?.collection.length === PROVIDER_CONNECTION_LIMIT) { + navigate(ADYEN_INTEGRATION_ROUTE) + } else { + navigate(INTEGRATIONS_ROUTE) + } + } return ( <> @@ -79,11 +115,52 @@ const AdyenIntegration = () => { ) : ( - {translate('text_645d071272418a14c1c76a6d')} + {adyenPaymentProvider?.name} )} + {translate('text_626162c62f790600f850b6fe')} + } + > + {({ closePopper }) => ( + + + + + )} + + {loading ? ( <> @@ -100,12 +177,13 @@ const AdyenIntegration = () => {
- - {translate('text_645d071272418a14c1c76a6d')} - + {adyenPaymentProvider?.name} - {translate('text_62b1edddbf5f461ab971271f')} + + {translate('text_645d071272418a14c1c76a6d')} •  + {translate('text_62b1edddbf5f461ab971271f')} +
)} @@ -115,54 +193,25 @@ const AdyenIntegration = () => {
{translate('text_645d071272418a14c1c76a9a')} - ( - - - - - - )} - + {translate('text_62b1edddbf5f461ab9712787')} + <> {loading ? ( <> - {[1, 2].map((i) => ( + {[0, 1, 2].map((i) => ( @@ -171,6 +220,32 @@ const AdyenIntegration = () => { ) : ( <> + + + + +
+ + {translate('text_626162c62f790600f850b76a')} + + + {adyenPaymentProvider?.name} + +
+
+ + + + +
+ + {translate('text_62876e85e32e0300e1803127')} + + + {adyenPaymentProvider?.code} + +
+
@@ -336,8 +411,8 @@ const AdyenIntegration = () => {
- - + + ) @@ -423,4 +498,4 @@ const Line = styled.div` } ` -export default AdyenIntegration +export default AdyenIntegrationDetails diff --git a/src/pages/settings/AdyenIntegrations.tsx b/src/pages/settings/AdyenIntegrations.tsx new file mode 100644 index 000000000..d99b7d38c --- /dev/null +++ b/src/pages/settings/AdyenIntegrations.tsx @@ -0,0 +1,322 @@ +import { gql } from '@apollo/client' +import { Stack } from '@mui/material' +import { useRef } from 'react' +import { generatePath, useNavigate } from 'react-router-dom' +import styled from 'styled-components' + +import { + Avatar, + Button, + ButtonLink, + Chip, + Icon, + Popper, + Skeleton, + Tooltip, + Typography, +} from '~/components/designSystem' +import { + AddAdyenDialog, + AddAdyenDialogRef, +} from '~/components/settings/integrations/AddAdyenDialog' +import { + AddEditDeleteSuccessRedirectUrlDialog, + AddEditDeleteSuccessRedirectUrlDialogRef, +} from '~/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog' +import { + DeleteAdyenIntegrationDialog, + DeleteAdyenIntegrationDialogRef, +} from '~/components/settings/integrations/DeleteAdyenIntegrationDialog' +import { ADYEN_INTEGRATION_DETAILS_ROUTE, INTEGRATIONS_ROUTE } from '~/core/router' +import { + AddAdyenProviderDialogFragmentDoc, + AdyenForCreateAndEditSuccessRedirectUrlFragmentDoc, + AdyenProvider, + DeleteAdyenIntegrationDialogFragmentDoc, + ProviderTypeEnum, + useGetAdyenIntegrationsListQuery, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' +import Adyen from '~/public/images/adyen.svg' +import { + ItemContainer, + ListItemLink, + MenuPopper, + NAV_HEIGHT, + PageHeader, + PopperOpener, + theme, +} from '~/styles' + +gql` + fragment AdyenIntegrations on AdyenProvider { + id + name + code + } + + query getAdyenIntegrationsList($limit: Int, $type: ProviderTypeEnum) { + paymentProviders(limit: $limit, type: $type) { + collection { + ... on AdyenProvider { + id + ...AdyenIntegrations + ...AddAdyenProviderDialog + ...DeleteAdyenIntegrationDialog + } + } + } + } + + ${AdyenForCreateAndEditSuccessRedirectUrlFragmentDoc} + ${DeleteAdyenIntegrationDialogFragmentDoc} + ${AddAdyenProviderDialogFragmentDoc} +` + +const AdyenIntegrations = () => { + const navigate = useNavigate() + const addAdyenDialogRef = useRef(null) + const deleteDialogRef = useRef(null) + const successRedirectUrlDialogRef = useRef(null) + const { translate } = useInternationalization() + const { data, loading } = useGetAdyenIntegrationsListQuery({ + variables: { limit: 1000, type: ProviderTypeEnum.Adyen }, + }) + const connections = data?.paymentProviders?.collection as AdyenProvider[] | undefined + const deleteDialogCallback = + connections && connections.length === 1 ? () => navigate(INTEGRATIONS_ROUTE) : undefined + + return ( + <> + + + + {loading ? ( + + ) : ( + + {translate('text_645d071272418a14c1c76a6d')} + + )} + + + + + {loading ? ( + <> + +
+ + +
+ + ) : ( + <> + + + +
+ + + {translate('text_645d071272418a14c1c76a6d')} + + + + {translate('text_62b1edddbf5f461ab971271f')} +
+ + )} +
+ + +
+ + {translate('text_65846763e6140b469140e239')} + + + <> + {loading ? ( + <> + {[1, 2].map((i) => ( + + + + + ))} + + ) : ( + <> + {connections?.map((connection, index) => { + return ( + + + + + + +
+ + {connection.name} + + + {connection.code} + +
+ +
+
+ ( + + + + + + )} + +
+ ) + })} + + )} + +
+
+ + + + + + ) +} + +const HeaderBlock = styled.div` + display: flex; + align-items: center; + + > *:first-child  { + margin-right: ${theme.spacing(3)}; + } +` + +const MainInfos = styled.div` + display: flex; + align-items: center; + padding: ${theme.spacing(8)} ${theme.spacing(12)}; +` + +const ListWrapper = styled.div` + display: flex; + flex-direction: column; + gap: ${theme.spacing(8)}; + margin: 0 ${theme.spacing(12)}; + box-sizing: border-box; + max-width: ${theme.spacing(168)}; +` + +const InlineTitle = styled.div` + position: relative; + height: ${NAV_HEIGHT}px; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; +` + +const LocalListItemLink = styled(ListItemLink)` + padding: 0; +` + +const ListItem = styled.div` + height: ${NAV_HEIGHT}px; + box-shadow: ${theme.shadows[7]}; + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(3)}; + } +` + +const StyledAvatar = styled(Avatar)` + margin-right: ${theme.spacing(4)}; +` + +const Line = styled.div` + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(2)}; + } +` + +const ButtonMock = styled.div` + width: 40px; + min-width: 40px; +` + +const LocalPopperOpener = styled(PopperOpener)` + right: 0; +` + +export default AdyenIntegrations diff --git a/src/pages/settings/GocardlessIntegration.tsx b/src/pages/settings/GocardlessIntegration.tsx deleted file mode 100644 index da6959dd8..000000000 --- a/src/pages/settings/GocardlessIntegration.tsx +++ /dev/null @@ -1,439 +0,0 @@ -import { gql } from '@apollo/client' -import { useEffect, useRef, useState } from 'react' -import { useLocation } from 'react-router-dom' -import styled from 'styled-components' - -import { - Avatar, - Button, - ButtonLink, - Chip, - Icon, - Popper, - Skeleton, - Tooltip, - Typography, -} from '~/components/designSystem' -import { - AddEditDeleteSuccessRedirectUrlDialog, - AddEditDeleteSuccessRedirectUrlDialogRef, -} from '~/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog' -import { envGlobalVar } from '~/core/apolloClient' -import { addToast } from '~/core/apolloClient' -import { INTEGRATIONS_ROUTE } from '~/core/router' -import { copyToClipboard } from '~/core/utils/copyToClipboard' -import { - GocardlessForCreateAndEditSuccessRedirectUrlFragmentDoc, - useAddGocardlessPaymentProviderMutation, - useGocardlessIntegrationsSettingQuery, -} from '~/generated/graphql' -import { useInternationalization } from '~/hooks/core/useInternationalization' -import GoCardless from '~/public/images/gocardless-large.svg' -import { - HEADER_TABLE_HEIGHT, - MenuPopper, - NAV_HEIGHT, - PageHeader, - PopperOpener, - theme, -} from '~/styles' - -gql` - query gocardlessIntegrationsSetting { - organization { - id - gocardlessPaymentProvider { - id - hasAccessToken - webhookSecret - successRedirectUrl - ...gocardlessForCreateAndEditSuccessRedirectUrl - } - } - } - - mutation addGocardlessPaymentProvider($input: AddGocardlessPaymentProviderInput!) { - addGocardlessPaymentProvider(input: $input) { - id - hasAccessToken - webhookSecret - successRedirectUrl - } - } - - ${GocardlessForCreateAndEditSuccessRedirectUrlFragmentDoc} -` - -const GocardlessIntegration = () => { - const { translate } = useInternationalization() - const { data, loading } = useGocardlessIntegrationsSettingQuery() - const query = new URLSearchParams(useLocation().search) - const code = query.get('code') - const successRedirectUrlDialogRef = useRef(null) - const [isConnectionEstablished, setIsConnectionEstablished] = useState(false) - const [webhookSecretKey, setWebhookSecretKey] = useState('') - const gocardlessPaymentProvider = data?.organization?.gocardlessPaymentProvider - const { lagoOauthProxyUrl } = envGlobalVar() - const [addPaymentProvider] = useAddGocardlessPaymentProviderMutation({ - onCompleted({ addGocardlessPaymentProvider }) { - if (addGocardlessPaymentProvider?.id && addGocardlessPaymentProvider?.webhookSecret) { - setIsConnectionEstablished(true) - setWebhookSecretKey(addGocardlessPaymentProvider?.webhookSecret) - addToast({ - message: translate('text_634ea0ecc6147de10ddb6645'), - severity: 'success', - }) - } - }, - }) - - useEffect(() => { - if (code) { - addPaymentProvider({ - variables: { - input: { - accessCode: code, - }, - }, - }) - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) - - useEffect(() => { - if (gocardlessPaymentProvider && gocardlessPaymentProvider.webhookSecret) { - setIsConnectionEstablished(true) - setWebhookSecretKey(gocardlessPaymentProvider.webhookSecret) - } - }, [gocardlessPaymentProvider]) - - return ( -
- - - - {loading ? ( - - ) : ( - - {translate('text_634ea0ecc6147de10ddb6629')} - - )} - - - - {loading ? ( - <> - -
- - -
- - ) : ( - <> - - - -
- - - {translate('text_634ea0ecc6147de10ddb6648')} - - {isConnectionEstablished && ( - - )} - - {translate('text_634ea0ecc6147de10ddb6643')} -
- - )} -
- - - - - {translate('text_634ea0ecc6147de10ddb663d')} - - - {isConnectionEstablished && ( - {translate('text_634ea0ecc6147de10ddb6641')} - )} - - -
- {translate('text_637f813d31381b1ed90ab315')} - - {loading ? ( - <> - - - - ) : ( - isConnectionEstablished && ( - <> - - - - - {webhookSecretKey} - - - - - - ) - )} - - {!loading && {translate('text_635bd8acb686f18909a57c93')}} -
- -
- - {translate('text_65367cb78324b77fcb6af21c')} - - - - {loading ? ( - - - - - ) : ( - <> - {!gocardlessPaymentProvider?.successRedirectUrl ? ( - - {translate('text_65367cb78324b77fcb6af226', { - connectionName: translate('text_634ea0ecc6147de10ddb6625'), - })} - - ) : ( - - - - - -
- - {translate('text_65367cb78324b77fcb6af1c6')} - - - {gocardlessPaymentProvider?.successRedirectUrl} - -
-
- ( - - - - - - )} - -
- )} - - )} -
-
- - -
- ) -} - -const HeaderBlock = styled.div` - display: flex; - align-items: center; - - > *:first-child  { - margin-right: ${theme.spacing(3)}; - } -` - -const MainInfos = styled.div` - display: flex; - align-items: center; - padding: ${theme.spacing(8)} ${theme.spacing(12)}; -` - -const ContentWrapper = styled.div` - max-width: ${theme.spacing(168)}; - margin: 0 ${theme.spacing(12)}; - display: flex; - flex-direction: column; - gap: ${theme.spacing(8)}; -` - -const MainHeader = styled.section` - box-shadow: ${theme.shadows[7]}; - padding-bottom: ${theme.spacing(8)}; -` - -const Title = styled(Typography)` - height: ${NAV_HEIGHT}px; - width: 100%; - display: flex; - align-items: center; -` - -const Head = styled.div` - height: ${NAV_HEIGHT}px; - display: flex; - justify-content: space-between; - align-items: center; -` - -const Subtitle = styled(Typography)` - height: ${HEADER_TABLE_HEIGHT}px; - width: 100%; - display: flex; - align-items: center; -` - -const SecretKeyItem = styled.div` - height: ${NAV_HEIGHT}px; - max-width: ${theme.spacing(168)}; - box-shadow: ${theme.shadows[7]}; - display: flex; - align-items: center; - - > *:first-child { - margin-right: ${theme.spacing(3)}; - } -` - -const SecretKey = styled(Typography)` - margin-right: auto; -` - -const Info = styled(Typography)` - height: ${HEADER_TABLE_HEIGHT}px; - display: flex; - justify-content: flex-start; - align-items: center; -` - -const StyledAvatar = styled(Avatar)` - margin-right: ${theme.spacing(4)}; -` - -const Line = styled.div` - display: flex; - align-items: center; - - > *:first-child { - margin-right: ${theme.spacing(2)}; - } -` - -const InlineTitle = styled.div` - position: relative; - height: ${NAV_HEIGHT}px; - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; -` - -const LocalPopper = styled(Popper)` - position: relative; - height: 100%; - > *:first-child { - right: 0; - top: 16px; - } -` - -const SuccessPaumentRedirectUrlItem = styled.div` - height: ${NAV_HEIGHT}px; - box-shadow: ${theme.shadows[7]}; - display: flex; - align-items: center; - justify-content: space-between; -` - -const SuccessPaumentRedirectUrlItemLeft = styled.div` - display: flex; - align-items: center; - gap: ${theme.spacing(3)}; -` - -export default GocardlessIntegration diff --git a/src/pages/settings/GocardlessIntegrationDetails.tsx b/src/pages/settings/GocardlessIntegrationDetails.tsx new file mode 100644 index 000000000..e4c82bb4b --- /dev/null +++ b/src/pages/settings/GocardlessIntegrationDetails.tsx @@ -0,0 +1,499 @@ +import { gql } from '@apollo/client' +import { Stack } from '@mui/material' +import { useRef } from 'react' +import { useNavigate, useParams } from 'react-router-dom' +import styled from 'styled-components' + +import { + Avatar, + Button, + ButtonLink, + Chip, + Icon, + Popper, + Skeleton, + Tooltip, + Typography, +} from '~/components/designSystem' +import { + AddEditDeleteSuccessRedirectUrlDialog, + AddEditDeleteSuccessRedirectUrlDialogRef, +} from '~/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog' +import { + AddGocardlessDialog, + AddGocardlessDialogRef, +} from '~/components/settings/integrations/AddGocardlessDialog' +import { + DeleteGocardlessIntegrationDialog, + DeleteGocardlessIntegrationDialogRef, +} from '~/components/settings/integrations/DeleteGocardlessIntegrationDialog' +import { envGlobalVar } from '~/core/apolloClient' +import { addToast } from '~/core/apolloClient' +import { GOCARDLESS_INTEGRATION_ROUTE, INTEGRATIONS_ROUTE } from '~/core/router' +import { copyToClipboard } from '~/core/utils/copyToClipboard' +import { + AddGocardlessProviderDialogFragmentDoc, + DeleteGocardlessIntegrationDialogFragmentDoc, + GocardlessIntegrationDetailsFragment, + ProviderTypeEnum, + useGetGocardlessIntegrationsDetailsQuery, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' +import GoCardless from '~/public/images/gocardless-large.svg' +import { MenuPopper, NAV_HEIGHT, PageHeader, PopperOpener, theme } from '~/styles' + +const PROVIDER_CONNECTION_LIMIT = 2 + +gql` + fragment GocardlessIntegrationDetails on GocardlessProvider { + id + code + name + successRedirectUrl + webhookSecret + } + + query getGocardlessIntegrationsDetails($id: ID!, $limit: Int, $type: ProviderTypeEnum) { + paymentProvider(id: $id) { + ... on GocardlessProvider { + id + ...GocardlessIntegrationDetails + ...DeleteGocardlessIntegrationDialog + ...AddGocardlessProviderDialog + } + } + + paymentProviders(limit: $limit, type: $type) { + collection { + ... on GocardlessProvider { + id + } + } + } + } + + ${DeleteGocardlessIntegrationDialogFragmentDoc} + ${AddGocardlessProviderDialogFragmentDoc} +` + +const GocardlessIntegrationDetails = () => { + const navigate = useNavigate() + const { integrationId } = useParams() + const { lagoOauthProxyUrl } = envGlobalVar() + const addDialogRef = useRef(null) + const deleteDialogRef = useRef(null) + const successRedirectUrlDialogRef = useRef(null) + const { translate } = useInternationalization() + const { data, loading } = useGetGocardlessIntegrationsDetailsQuery({ + variables: { + id: integrationId as string, + limit: PROVIDER_CONNECTION_LIMIT, + type: ProviderTypeEnum.Gocardless, + }, + skip: !integrationId, + }) + const gocardlessPaymentProvider = data?.paymentProvider as GocardlessIntegrationDetailsFragment + const isConnectionEstablished = !!gocardlessPaymentProvider?.webhookSecret + const deleteDialogCallback = () => { + if (data?.paymentProviders?.collection.length === PROVIDER_CONNECTION_LIMIT) { + navigate(GOCARDLESS_INTEGRATION_ROUTE) + } else { + navigate(INTEGRATIONS_ROUTE) + } + } + + return ( +
+ + + + {loading ? ( + + ) : ( + + {gocardlessPaymentProvider?.name} + + )} + + {translate('text_626162c62f790600f850b6fe')} + } + > + {({ closePopper }) => ( + + + + + + )} + + + + {loading ? ( + <> + +
+ + +
+ + ) : ( + <> + + + +
+ + {gocardlessPaymentProvider?.name} + {isConnectionEstablished && ( + + )} + + + {translate('text_634ea0ecc6147de10ddb6648')} •  + {translate('text_62b1edddbf5f461ab971271f')} + +
+ + )} +
+ + +
+ + {translate('text_637f813d31381b1ed90ab315')} + + + {loading ? ( + <> + {[0, 1, 2].map((i) => ( + + + + + ))} +
+ + + ) : ( + <> + {isConnectionEstablished && ( + <> + + + + + + + {translate('text_626162c62f790600f850b76a')} + + + {gocardlessPaymentProvider.name} + + + + + + + + + + + {translate('text_62876e85e32e0300e1803127')}{' '} + + + {gocardlessPaymentProvider.code} + + + + + + + + + + + + {translate('text_658567dffff71e31ea5f0d3e')} + + + {gocardlessPaymentProvider.webhookSecret} + + + + + + + + + )} + + )} + {!loading && {translate('text_635bd8acb686f18909a57c93')}} +
+ +
+ + {translate('text_65367cb78324b77fcb6af21c')} + + + + {loading ? ( + + + + + ) : ( + <> + {!gocardlessPaymentProvider?.successRedirectUrl ? ( + + {translate('text_65367cb78324b77fcb6af226', { + connectionName: translate('text_634ea0ecc6147de10ddb6625'), + })} + + ) : ( + + + + + +
+ + {translate('text_65367cb78324b77fcb6af1c6')} + + + {gocardlessPaymentProvider?.successRedirectUrl} + +
+
+ ( + + + + + + )} + +
+ )} + + )} +
+
+ + + + +
+ ) +} + +const HeaderBlock = styled.div` + display: flex; + align-items: center; + + > *:first-child  { + margin-right: ${theme.spacing(3)}; + } +` + +const MainInfos = styled.div` + display: flex; + align-items: center; + padding: ${theme.spacing(8)} ${theme.spacing(12)}; +` + +const ContentWrapper = styled.div` + max-width: ${theme.spacing(168)}; + margin: 0 ${theme.spacing(12)}; + display: flex; + flex-direction: column; + gap: ${theme.spacing(8)}; +` + +const Title = styled(Typography)` + height: ${NAV_HEIGHT}px; + width: 100%; + display: flex; + align-items: center; +` + +const Item = styled(Stack)` + height: ${NAV_HEIGHT}px; + max-width: ${theme.spacing(168)}; + box-shadow: ${theme.shadows[7]}; +` + +const Info = styled(Typography)` + margin-top: ${theme.spacing(3)}; +` + +const StyledAvatar = styled(Avatar)` + margin-right: ${theme.spacing(4)}; +` + +const Line = styled.div` + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(2)}; + } +` + +const InlineTitle = styled.div` + position: relative; + height: ${NAV_HEIGHT}px; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; +` + +const LocalPopper = styled(Popper)` + position: relative; + height: 100%; + > *:first-child { + right: 0; + top: 16px; + } +` + +const SuccessPaumentRedirectUrlItem = styled.div` + height: ${NAV_HEIGHT}px; + box-shadow: ${theme.shadows[7]}; + display: flex; + align-items: center; + justify-content: space-between; +` + +const SuccessPaumentRedirectUrlItemLeft = styled.div` + display: flex; + align-items: center; + gap: ${theme.spacing(3)}; +` + +export default GocardlessIntegrationDetails diff --git a/src/pages/settings/GocardlessIntegrationOauthCallback.tsx b/src/pages/settings/GocardlessIntegrationOauthCallback.tsx new file mode 100644 index 000000000..aa8d960da --- /dev/null +++ b/src/pages/settings/GocardlessIntegrationOauthCallback.tsx @@ -0,0 +1,180 @@ +import { gql } from '@apollo/client' +import { useEffect } from 'react' +import { generatePath, useNavigate, useSearchParams } from 'react-router-dom' +import styled from 'styled-components' + +import { Avatar, ButtonLink, Chip, Icon, Skeleton, Typography } from '~/components/designSystem' +import { GenericPlaceholder } from '~/components/GenericPlaceholder' +import { addToast } from '~/core/apolloClient' +import { GOCARDLESS_INTEGRATION_DETAILS_ROUTE, INTEGRATIONS_ROUTE } from '~/core/router' +import { + AddGocardlessProviderDialogFragmentDoc, + useAddGocardlessApiKeyMutation, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' +import Gocardless from '~/public/images/gocardless.svg' +import ErrorImage from '~/public/images/maneki/error.svg' +import { PageHeader, theme } from '~/styles' + +gql` + fragment GocardlessIntegrationOauthCallback on GocardlessProvider { + id + name + code + } + + mutation addGocardlessApiKey($input: AddGocardlessPaymentProviderInput!) { + addGocardlessPaymentProvider(input: $input) { + id + ...AddGocardlessProviderDialog + ...GocardlessIntegrationOauthCallback + } + } + + ${AddGocardlessProviderDialogFragmentDoc} +` + +const GocardlessIntegrationOauthCallback = () => { + let [searchParams] = useSearchParams() + const accessCode = searchParams.get('code') || '' + const code = searchParams.get('lago_code') || '' + const name = searchParams.get('lago_name') || '' + + const navigate = useNavigate() + const { translate } = useInternationalization() + const [addGocardlessApiKey, { loading, error }] = useAddGocardlessApiKeyMutation() + + useEffect(() => { + const createIntegration = async () => { + const res = await addGocardlessApiKey({ + variables: { + input: { + accessCode, + code, + name, + }, + }, + }) + + navigate( + generatePath(GOCARDLESS_INTEGRATION_DETAILS_ROUTE, { + integrationId: res.data?.addGocardlessPaymentProvider?.id as string, + }), + ) + } + + if (!!code && !!accessCode && !!name) { + createIntegration() + } else { + navigate(INTEGRATIONS_ROUTE) + + addToast({ + severity: 'danger', + translateKey: 'text_622f7a3dc32ce100c46a5154', + }) + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + return ( + <> + + + + {loading ? ( + + ) : ( + + {translate('text_634ea0ecc6147de10ddb6625')} + + )} + + + + {loading ? ( + <> + +
+ + +
+ + ) : ( + <> + + + +
+ + + {translate('text_634ea0ecc6147de10ddb6625')} + + + + {translate('text_62b1edddbf5f461ab971271f')} +
+ + )} +
+ + {loading || !error ? ( + + + + ) : ( + } + title={translate('text_62bac37900192b773560e82d')} + subtitle={translate('text_62bac37900192b773560e82f')} + buttonTitle={translate('text_62bac37900192b773560e831')} + buttonAction={() => navigate(INTEGRATIONS_ROUTE)} + /> + )} + + ) +} + +const HeaderBlock = styled.div` + display: flex; + align-items: center; + + > *:first-child  { + margin-right: ${theme.spacing(3)}; + } +` + +const MainInfos = styled.div` + display: flex; + align-items: center; + padding: ${theme.spacing(8)} ${theme.spacing(12)}; +` + +const StyledAvatar = styled(Avatar)` + margin-right: ${theme.spacing(4)}; +` + +const Line = styled.div` + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(2)}; + } +` + +const Loader = styled.div` + height: 100%; + width: 100%; + margin: auto; + display: flex; + align-items: center; + justify-content: center; +` + +export default GocardlessIntegrationOauthCallback diff --git a/src/pages/settings/GocardlessIntegrations.tsx b/src/pages/settings/GocardlessIntegrations.tsx new file mode 100644 index 000000000..7c3aae0e7 --- /dev/null +++ b/src/pages/settings/GocardlessIntegrations.tsx @@ -0,0 +1,322 @@ +import { gql } from '@apollo/client' +import { Stack } from '@mui/material' +import { useRef } from 'react' +import { generatePath, useNavigate } from 'react-router-dom' +import styled from 'styled-components' + +import { + Avatar, + Button, + ButtonLink, + Chip, + Icon, + Popper, + Skeleton, + Tooltip, + Typography, +} from '~/components/designSystem' +import { + AddEditDeleteSuccessRedirectUrlDialog, + AddEditDeleteSuccessRedirectUrlDialogRef, +} from '~/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog' +import { + AddGocardlessDialog, + AddGocardlessDialogRef, +} from '~/components/settings/integrations/AddGocardlessDialog' +import { + DeleteGocardlessIntegrationDialog, + DeleteGocardlessIntegrationDialogRef, +} from '~/components/settings/integrations/DeleteGocardlessIntegrationDialog' +import { GOCARDLESS_INTEGRATION_DETAILS_ROUTE, INTEGRATIONS_ROUTE } from '~/core/router' +import { + AddGocardlessProviderDialogFragmentDoc, + DeleteGocardlessIntegrationDialogFragmentDoc, + GocardlessForCreateAndEditSuccessRedirectUrlFragmentDoc, + GocardlessProvider, + ProviderTypeEnum, + useGetGocardlessIntegrationsListQuery, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' +import Gocardless from '~/public/images/gocardless.svg' +import { + ItemContainer, + ListItemLink, + MenuPopper, + NAV_HEIGHT, + PageHeader, + PopperOpener, + theme, +} from '~/styles' + +gql` + fragment GocardlessIntegrations on GocardlessProvider { + id + name + code + } + + query getGocardlessIntegrationsList($limit: Int, $type: ProviderTypeEnum) { + paymentProviders(limit: $limit, type: $type) { + collection { + ... on GocardlessProvider { + id + ...GocardlessIntegrations + ...AddGocardlessProviderDialog + ...DeleteGocardlessIntegrationDialog + } + } + } + } + + ${GocardlessForCreateAndEditSuccessRedirectUrlFragmentDoc} + ${DeleteGocardlessIntegrationDialogFragmentDoc} + ${AddGocardlessProviderDialogFragmentDoc} +` + +const GocardlessIntegrations = () => { + const navigate = useNavigate() + const addGocardlessDialogRef = useRef(null) + const deleteDialogRef = useRef(null) + const successRedirectUrlDialogRef = useRef(null) + const { translate } = useInternationalization() + const { data, loading } = useGetGocardlessIntegrationsListQuery({ + variables: { limit: 1000, type: ProviderTypeEnum.Gocardless }, + }) + const connections = data?.paymentProviders?.collection as GocardlessProvider[] | undefined + const deleteDialogCallback = + connections && connections.length === 1 ? () => navigate(INTEGRATIONS_ROUTE) : undefined + + return ( + <> + + + + {loading ? ( + + ) : ( + + {translate('text_634ea0ecc6147de10ddb6625')} + + )} + + + + + {loading ? ( + <> + +
+ + +
+ + ) : ( + <> + + + +
+ + + {translate('text_634ea0ecc6147de10ddb6625')} + + + + {translate('text_62b1edddbf5f461ab971271f')} +
+ + )} +
+ + +
+ + {translate('text_65846763e6140b469140e239')} + + + <> + {loading ? ( + <> + {[1, 2].map((i) => ( + + + + + ))} + + ) : ( + <> + {connections?.map((connection, index) => { + return ( + + + + + + +
+ + {connection.name} + + + {connection.code} + +
+ +
+
+ ( + + + + + + )} + +
+ ) + })} + + )} + +
+
+ + + + + + ) +} + +const HeaderBlock = styled.div` + display: flex; + align-items: center; + + > *:first-child  { + margin-right: ${theme.spacing(3)}; + } +` + +const MainInfos = styled.div` + display: flex; + align-items: center; + padding: ${theme.spacing(8)} ${theme.spacing(12)}; +` + +const ListWrapper = styled.div` + display: flex; + flex-direction: column; + gap: ${theme.spacing(8)}; + margin: 0 ${theme.spacing(12)}; + box-sizing: border-box; + max-width: ${theme.spacing(168)}; +` + +const InlineTitle = styled.div` + position: relative; + height: ${NAV_HEIGHT}px; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; +` + +const LocalListItemLink = styled(ListItemLink)` + padding: 0; +` + +const ListItem = styled.div` + height: ${NAV_HEIGHT}px; + box-shadow: ${theme.shadows[7]}; + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(3)}; + } +` + +const StyledAvatar = styled(Avatar)` + margin-right: ${theme.spacing(4)}; +` + +const Line = styled.div` + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(2)}; + } +` + +const ButtonMock = styled.div` + width: 40px; + min-width: 40px; +` + +const LocalPopperOpener = styled(PopperOpener)` + right: 0; +` + +export default GocardlessIntegrations diff --git a/src/pages/settings/Integrations.tsx b/src/pages/settings/Integrations.tsx index 9ec9a5891..41cd14161 100644 --- a/src/pages/settings/Integrations.tsx +++ b/src/pages/settings/Integrations.tsx @@ -8,6 +8,10 @@ import { AddAdyenDialog, AddAdyenDialogRef, } from '~/components/settings/integrations/AddAdyenDialog' +import { + AddGocardlessDialog, + AddGocardlessDialogRef, +} from '~/components/settings/integrations/AddGocardlessDialog' import { AddLagoTaxManagementDialog, AddLagoTaxManagementDialogRef, @@ -16,7 +20,6 @@ import { AddStripeDialog, AddStripeDialogRef, } from '~/components/settings/integrations/AddStripeDialog' -import { envGlobalVar } from '~/core/apolloClient' import { DOCUMENTATION_AIRBYTE, DOCUMENTATION_HIGHTTOUCH, @@ -42,19 +45,26 @@ import Stripe from '~/public/images/stripe.svg' import { theme } from '~/styles' gql` - query integrationsSetting { + query integrationsSetting($limit: Int) { organization { id euTaxManagement country - stripePaymentProvider { - id - } - gocardlessPaymentProvider { - id - } - adyenPaymentProvider { - id + } + + paymentProviders(limit: $limit) { + collection { + ... on StripeProvider { + id + } + + ... on GocardlessProvider { + id + } + + ... on AdyenProvider { + id + } } } } @@ -65,15 +75,23 @@ const Integrations = () => { const navigate = useNavigate() const addStripeDialogRef = useRef(null) const addAdyenDialogRef = useRef(null) + const addGocardlessnDialogRef = useRef(null) const addLagoTaxManagementDialog = useRef(null) - const { data, loading } = useIntegrationsSettingQuery() + const { data, loading } = useIntegrationsSettingQuery({ + variables: { limit: 1000 }, + }) const organization = data?.organization - const hasAdyenIntegration = !!organization?.adyenPaymentProvider?.id - const hasStripeIntegration = !!organization?.stripePaymentProvider?.id - const hasGocardlessIntegration = !!organization?.gocardlessPaymentProvider?.id + const hasAdyenIntegration = data?.paymentProviders?.collection?.some( + (provider) => provider?.__typename === 'AdyenProvider', + ) + const hasStripeIntegration = data?.paymentProviders?.collection?.some( + (provider) => provider?.__typename === 'StripeProvider', + ) + const hasGocardlessIntegration = data?.paymentProviders?.collection?.some( + (provider) => provider?.__typename === 'GocardlessProvider', + ) const hasTaxManagement = !!organization?.euTaxManagement - const { lagoOauthProxyUrl } = envGlobalVar() return ( @@ -149,7 +167,7 @@ const Integrations = () => { if (hasGocardlessIntegration) { navigate(GOCARDLESS_INTEGRATION_ROUTE) } else { - window.open(`${lagoOauthProxyUrl}/gocardless/auth`, '_blank') + addGocardlessnDialogRef.current?.openDialog() } }} fullWidth @@ -177,9 +195,6 @@ const Integrations = () => { if (hasTaxManagement) { navigate(TAX_MANAGEMENT_INTEGRATION_ROUTE) } else { - const element = document.activeElement as HTMLElement - - element.blur && element.blur() addLagoTaxManagementDialog.current?.openDialog() } }} @@ -223,6 +238,7 @@ const Integrations = () => { + { } const Page = styled.div` + max-width: 672px; padding: ${theme.spacing(8)} ${theme.spacing(12)}; ` diff --git a/src/pages/settings/StripeIntegration.tsx b/src/pages/settings/StripeIntegrationDetails.tsx similarity index 58% rename from src/pages/settings/StripeIntegration.tsx rename to src/pages/settings/StripeIntegrationDetails.tsx index 4721997df..f93e72e1b 100644 --- a/src/pages/settings/StripeIntegration.tsx +++ b/src/pages/settings/StripeIntegrationDetails.tsx @@ -1,5 +1,7 @@ import { gql } from '@apollo/client' +import { Stack } from '@mui/material' import { useRef } from 'react' +import { useNavigate, useParams } from 'react-router-dom' import styled from 'styled-components' import { @@ -25,50 +27,85 @@ import { DeleteStripeIntegrationDialog, DeleteStripeIntegrationDialogRef, } from '~/components/settings/integrations/DeleteStripeIntegrationDialog' -import { INTEGRATIONS_ROUTE } from '~/core/router' -import { useStripeIntegrationsSettingQuery } from '~/generated/graphql' +import { INTEGRATIONS_ROUTE, STRIPE_INTEGRATION_ROUTE } from '~/core/router' +import { + AddStripeProviderDialogFragmentDoc, + DeleteStripeIntegrationDialogFragmentDoc, + ProviderTypeEnum, + StripeForCreateAndEditSuccessRedirectUrlFragmentDoc, + StripeIntegrationDetailsFragment, + useGetStripeIntegrationsDetailsQuery, +} from '~/generated/graphql' import { useInternationalization } from '~/hooks/core/useInternationalization' import Stripe from '~/public/images/stripe.svg' import { MenuPopper, NAV_HEIGHT, PageHeader, PopperOpener, theme } from '~/styles' +const PROVIDER_CONNECTION_LIMIT = 2 + gql` - fragment StripeIntegration on StripeProvider { + fragment StripeIntegrationDetails on StripeProvider { id + code + name secretKey - createCustomers successRedirectUrl } - query stripeIntegrationsSetting { - organization { - id - stripePaymentProvider { - ...StripeIntegration + query getStripeIntegrationsDetails($id: ID!, $limit: Int, $type: ProviderTypeEnum) { + paymentProvider(id: $id) { + ... on StripeProvider { + id + ...StripeIntegrationDetails + ...DeleteStripeIntegrationDialog + ...AddStripeProviderDialog + ...StripeForCreateAndEditSuccessRedirectUrl } } - } - mutation updateStripeIntegration($input: AddStripePaymentProviderInput!) { - addStripePaymentProvider(input: $input) { - ...StripeIntegration + paymentProviders(limit: $limit, type: $type) { + collection { + ... on StripeProvider { + id + } + } } } + + ${DeleteStripeIntegrationDialogFragmentDoc} + ${AddStripeProviderDialogFragmentDoc} + ${StripeForCreateAndEditSuccessRedirectUrlFragmentDoc} ` -const StripeIntegration = () => { +const StripeIntegrationDetails = () => { + const navigate = useNavigate() + const { integrationId } = useParams() const addDialogRef = useRef(null) const deleteDialogRef = useRef(null) const successRedirectUrlDialogRef = useRef(null) const { translate } = useInternationalization() - const { data, loading } = useStripeIntegrationsSettingQuery() - const stripePaymentProvider = data?.organization?.stripePaymentProvider + const { data, loading } = useGetStripeIntegrationsDetailsQuery({ + variables: { + id: integrationId as string, + limit: PROVIDER_CONNECTION_LIMIT, + type: ProviderTypeEnum.Stripe, + }, + skip: !integrationId, + }) + const stripePaymentProvider = data?.paymentProvider as StripeIntegrationDetailsFragment + const deleteDialogCallback = () => { + if (data?.paymentProviders?.collection.length === PROVIDER_CONNECTION_LIMIT) { + navigate(STRIPE_INTEGRATION_ROUTE) + } else { + navigate(INTEGRATIONS_ROUTE) + } + } return ( -
+ <> @@ -76,11 +113,52 @@ const StripeIntegration = () => { ) : ( - {translate('text_62b1edddbf5f461ab97126ee')} + {stripePaymentProvider?.name} )} + {translate('text_626162c62f790600f850b6fe')} + } + > + {({ closePopper }) => ( + + + + + )} + + {loading ? ( <> @@ -97,12 +175,13 @@ const StripeIntegration = () => {
- - {translate('text_62b1edddbf5f461ab9712707')} - + {stripePaymentProvider?.name} - {translate('text_62b1edddbf5f461ab971271f')} + + {translate('text_62b1edddbf5f461ab9712707')} •  + {translate('text_62b1edddbf5f461ab971271f')} +
)} @@ -110,8 +189,64 @@ const StripeIntegration = () => {
- {translate('text_62b1edddbf5f461ab971273f')} - + + {translate('text_657078c28394d6b1ae1b9725')} + + + + + {loading ? ( + <> + + + + ) : ( + <> + + + + + + {translate('text_626162c62f790600f850b76a')} + + {stripePaymentProvider?.name} + + + )} + + + {loading ? ( + <> + + + + ) : ( + <> + + + + + + {translate('text_62876e85e32e0300e1803127')} + + {stripePaymentProvider?.code} + + + )} + + {loading ? ( <> @@ -122,45 +257,18 @@ const StripeIntegration = () => { - {stripePaymentProvider?.secretKey} - } - > - {({ closePopper }) => ( - - - - - )} - + + + {translate('text_62b1edddbf5f461ab9712748')} + + {stripePaymentProvider?.secretKey} + )} - - + + {translate('text_637f813d31381b1ed90ab30e')} - +
@@ -168,7 +276,7 @@ const StripeIntegration = () => { {translate('text_65367cb78324b77fcb6af21c')}
- - + + -
+ ) } @@ -305,19 +413,22 @@ const Title = styled(Typography)` align-items: center; ` -const ApiKeyItem = styled.div` +const LineItem = styled.div` height: ${NAV_HEIGHT}px; max-width: ${theme.spacing(168)}; box-shadow: ${theme.shadows[7]}; display: flex; align-items: center; - margin-bottom: ${theme.spacing(3)}; > *:first-child { margin-right: ${theme.spacing(3)}; } ` +const LineItemCaption = styled(Typography)` + margin-top: ${theme.spacing(3)}; +` + const StyledAvatar = styled(Avatar)` margin-right: ${theme.spacing(4)}; ` @@ -331,10 +442,6 @@ const Line = styled.div` } ` -const ApiKey = styled(Typography)` - margin-right: auto; -` - const InlineTitle = styled.div` position: relative; height: ${NAV_HEIGHT}px; @@ -367,4 +474,4 @@ const SuccessPaumentRedirectUrlItemLeft = styled.div` gap: ${theme.spacing(3)}; ` -export default StripeIntegration +export default StripeIntegrationDetails diff --git a/src/pages/settings/StripeIntegrations.tsx b/src/pages/settings/StripeIntegrations.tsx new file mode 100644 index 000000000..f69c00313 --- /dev/null +++ b/src/pages/settings/StripeIntegrations.tsx @@ -0,0 +1,322 @@ +import { gql } from '@apollo/client' +import { Stack } from '@mui/material' +import { useRef } from 'react' +import { generatePath, useNavigate } from 'react-router-dom' +import styled from 'styled-components' + +import { + Avatar, + Button, + ButtonLink, + Chip, + Icon, + Popper, + Skeleton, + Tooltip, + Typography, +} from '~/components/designSystem' +import { + AddEditDeleteSuccessRedirectUrlDialog, + AddEditDeleteSuccessRedirectUrlDialogRef, +} from '~/components/settings/integrations/AddEditDeleteSuccessRedirectUrlDialog' +import { + AddStripeDialog, + AddStripeDialogRef, +} from '~/components/settings/integrations/AddStripeDialog' +import { + DeleteStripeIntegrationDialog, + DeleteStripeIntegrationDialogRef, +} from '~/components/settings/integrations/DeleteStripeIntegrationDialog' +import { INTEGRATIONS_ROUTE, STRIPE_INTEGRATION_DETAILS_ROUTE } from '~/core/router' +import { + AddStripeProviderDialogFragmentDoc, + DeleteStripeIntegrationDialogFragmentDoc, + ProviderTypeEnum, + StripeForCreateAndEditSuccessRedirectUrlFragmentDoc, + StripeProvider, + useGetStripeIntegrationsListQuery, +} from '~/generated/graphql' +import { useInternationalization } from '~/hooks/core/useInternationalization' +import Stripe from '~/public/images/stripe.svg' +import { + ItemContainer, + ListItemLink, + MenuPopper, + NAV_HEIGHT, + PageHeader, + PopperOpener, + theme, +} from '~/styles' + +gql` + fragment StripeIntegrations on StripeProvider { + id + name + code + } + + query getStripeIntegrationsList($limit: Int, $type: ProviderTypeEnum) { + paymentProviders(limit: $limit, type: $type) { + collection { + ... on StripeProvider { + id + ...StripeIntegrations + ...AddStripeProviderDialog + ...DeleteStripeIntegrationDialog + } + } + } + } + + ${StripeForCreateAndEditSuccessRedirectUrlFragmentDoc} + ${DeleteStripeIntegrationDialogFragmentDoc} + ${AddStripeProviderDialogFragmentDoc} +` + +const StripeIntegrations = () => { + const navigate = useNavigate() + const addStripeDialogRef = useRef(null) + const deleteDialogRef = useRef(null) + const successRedirectUrlDialogRef = useRef(null) + const { translate } = useInternationalization() + const { data, loading } = useGetStripeIntegrationsListQuery({ + variables: { limit: 1000, type: ProviderTypeEnum.Stripe }, + }) + const connections = data?.paymentProviders?.collection as StripeProvider[] | undefined + const deleteDialogCallback = + connections && connections.length === 1 ? () => navigate(INTEGRATIONS_ROUTE) : undefined + + return ( + <> + + + + {loading ? ( + + ) : ( + + {translate('text_62b1edddbf5f461ab971277d')} + + )} + + + + + {loading ? ( + <> + +
+ + +
+ + ) : ( + <> + + + +
+ + + {translate('text_62b1edddbf5f461ab971277d')} + + + + {translate('text_62b1edddbf5f461ab971271f')} +
+ + )} +
+ + +
+ + {translate('text_65846763e6140b469140e239')} + + + <> + {loading ? ( + <> + {[1, 2].map((i) => ( + + + + + ))} + + ) : ( + <> + {connections?.map((connection, index) => { + return ( + + + + + + +
+ + {connection.name} + + + {connection.code} + +
+ +
+
+ ( + + + + + + )} + +
+ ) + })} + + )} + +
+
+ + + + + + ) +} + +const HeaderBlock = styled.div` + display: flex; + align-items: center; + + > *:first-child  { + margin-right: ${theme.spacing(3)}; + } +` + +const MainInfos = styled.div` + display: flex; + align-items: center; + padding: ${theme.spacing(8)} ${theme.spacing(12)}; +` + +const ListWrapper = styled.div` + display: flex; + flex-direction: column; + gap: ${theme.spacing(8)}; + margin: 0 ${theme.spacing(12)}; + box-sizing: border-box; + max-width: ${theme.spacing(168)}; +` + +const InlineTitle = styled.div` + position: relative; + height: ${NAV_HEIGHT}px; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; +` + +const LocalListItemLink = styled(ListItemLink)` + padding: 0; +` + +const ListItem = styled.div` + height: ${NAV_HEIGHT}px; + box-shadow: ${theme.shadows[7]}; + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(3)}; + } +` + +const StyledAvatar = styled(Avatar)` + margin-right: ${theme.spacing(4)}; +` + +const Line = styled.div` + display: flex; + align-items: center; + + > *:first-child { + margin-right: ${theme.spacing(2)}; + } +` + +const ButtonMock = styled.div` + width: 40px; + min-width: 40px; +` + +const LocalPopperOpener = styled(PopperOpener)` + right: 0; +` + +export default StripeIntegrations diff --git a/src/public/icons/coin-dollar.svg b/src/public/icons/coin-dollar.svg index cf9be1cb4..d080662e2 100644 --- a/src/public/icons/coin-dollar.svg +++ b/src/public/icons/coin-dollar.svg @@ -1,13 +1,8 @@ - - - - - - + diff --git a/src/public/icons/flash-filled.svg b/src/public/icons/flash-filled.svg index c113b0ad0..d00cca2bf 100644 --- a/src/public/icons/flash-filled.svg +++ b/src/public/icons/flash-filled.svg @@ -1,13 +1,7 @@ - + diff --git a/src/public/images/favicon-local.svg b/src/public/images/favicon-local.svg index ddae27592..f1ca5bfa8 100644 --- a/src/public/images/favicon-local.svg +++ b/src/public/images/favicon-local.svg @@ -1,24 +1,16 @@ - - - + + + - - - - - diff --git a/src/public/images/favicon-prod.svg b/src/public/images/favicon-prod.svg index 2b36842af..fbf77d51d 100644 --- a/src/public/images/favicon-prod.svg +++ b/src/public/images/favicon-prod.svg @@ -1,24 +1,16 @@ - - - + + + - - - - - diff --git a/src/public/images/favicon-staging.svg b/src/public/images/favicon-staging.svg index d2b287bad..be582dbd3 100644 --- a/src/public/images/favicon-staging.svg +++ b/src/public/images/favicon-staging.svg @@ -1,24 +1,16 @@ - - - + + + - - - - - diff --git a/src/public/images/gocardless-large.svg b/src/public/images/gocardless-large.svg index 9c9af6093..e3fff3501 100644 --- a/src/public/images/gocardless-large.svg +++ b/src/public/images/gocardless-large.svg @@ -1,7 +1,7 @@ - - + + diff --git a/src/public/images/gocardless.svg b/src/public/images/gocardless.svg index 28c8a0fb1..d8497bfff 100644 --- a/src/public/images/gocardless.svg +++ b/src/public/images/gocardless.svg @@ -1,14 +1,7 @@ - - - - - - - - - - + + + diff --git a/src/public/images/logo/lago-logo-grey.svg b/src/public/images/logo/lago-logo-grey.svg index 8a166d29e..192bac69b 100644 --- a/src/public/images/logo/lago-logo-grey.svg +++ b/src/public/images/logo/lago-logo-grey.svg @@ -1,30 +1,19 @@ - - - - - - - - - - - + + + + + - - - - - - diff --git a/src/public/images/logo/lago-logo.svg b/src/public/images/logo/lago-logo.svg index 2147f3275..51a35a6ac 100644 --- a/src/public/images/logo/lago-logo.svg +++ b/src/public/images/logo/lago-logo.svg @@ -1,30 +1,19 @@ - - - - - - - - - - - + + + + + - - - - - - diff --git a/src/public/images/oso.svg b/src/public/images/oso.svg index fcb7912ba..54690064f 100644 --- a/src/public/images/oso.svg +++ b/src/public/images/oso.svg @@ -1,17 +1,15 @@ - - - - - + + + diff --git a/yarn.lock b/yarn.lock index 6b8d66442..1ae21240e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3002,10 +3002,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@29.5.10": - version "29.5.10" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.10.tgz#a10fc5bab9e426081c12b2ef73d24d4f0c9b7f50" - integrity sha512-tE4yxKEphEyxj9s4inideLHktW/x6DwesIwWZ9NN1FKf9zbJYsnhBoA9vrHA/IuIOKwPa5PcFBNV4lpMIOEzyQ== +"@types/jest@29.5.11": + version "29.5.11" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.11.tgz#0c13aa0da7d0929f078ab080ae5d4ced80fa2f2c" + integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -3221,10 +3221,10 @@ resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/styled-components@5.1.32": - version "5.1.32" - resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.32.tgz#58718971519c4562229ba85face98e8530d21bfd" - integrity sha512-DqVpl8R0vbhVSop4120UHtGrFmHuPeoDwF4hDT0kPJTY8ty0SI38RV3VhCMsWigMUXG+kCXu7vMRqMFNy6eQgA== +"@types/styled-components@5.1.34": + version "5.1.34" + resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.34.tgz#4107df8ef8a7eaba4fa6b05f78f93fba4daf0300" + integrity sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA== dependencies: "@types/hoist-non-react-statics" "*" "@types/react" "*" @@ -5714,10 +5714,10 @@ eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" -eslint-plugin-import@2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" - integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== +eslint-plugin-import@2.29.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== dependencies: array-includes "^3.1.7" array.prototype.findlastindex "^1.2.3" @@ -5735,7 +5735,7 @@ eslint-plugin-import@2.29.0: object.groupby "^1.0.1" object.values "^1.1.7" semver "^6.3.1" - tsconfig-paths "^3.14.2" + tsconfig-paths "^3.15.0" eslint-plugin-jsx-a11y@6.8.0: version "6.8.0" @@ -10416,10 +10416,10 @@ ts-log@^2.2.3: resolved "https://registry.npmjs.org/ts-log/-/ts-log-2.2.4.tgz" integrity sha512-DEQrfv6l7IvN2jlzc/VTdZJYsWUnQNCsueYjMkC/iXoEoi5fNan6MjeDqkvhfzbmHgdz9UxDUluX3V5HdjTydQ== -tsconfig-paths@^3.14.2: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.2"