# Instructions

- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.

# Test info

- Name: src/manager/tests/e2e/booking/booking-create.spec.ts >> rejects a sepa booking over the payment amount limit
- Location: src/manager/tests/e2e/booking/booking-create.spec.ts:954:5

# Error details

```
Error: expect(locator).toBeVisible() failed

Locator: locator('.v-snackbar').filter({ hasText: 'Max billing amount exceeded for payment method type' })
Expected: visible
Timeout: 30000ms
Error: element(s) not found

Call log:
  - Expect "toBeVisible" with timeout 30000ms
  - waiting for locator('.v-snackbar').filter({ hasText: 'Max billing amount exceeded for payment method type' })

```

```yaml
- navigation:
  - link:
    - /url: /
  - text: KINNOVIS Manager
  - button:
    - img
  - list:
    - text: Dashboard
    - link "Tasks":
      - /url: /tasks
      - img
      - text: Tasks
    - link "Facility maps":
      - /url: /facility-map
    - link "Analytics":
      - /url: /dashboard
    - text: Sales
    - link "Bookings":
      - /url: /bookings
    - link "Customers":
      - /url: /customers
    - link "Invoices":
      - /url: /invoices
    - link "Credit notes":
      - /url: /credit-notes
      - img
      - text: Credit notes
    - link "Units":
      - /url: /units
    - text: Site management
    - link "Locations":
      - /url: /locations
    - link "Unit types":
      - /url: /unit-types
    - link "Protection Plans":
      - /url: /insurances
    - link "Deposits":
      - /url: /deposits
    - link "Products":
      - /url: /products
    - link "Discounts":
      - /url: /discounts
    - option "Emails"
    - link "Document templates":
      - /url: /document-templates
    - text: Admin
    - link "Integrations":
      - /url: /connected-apps
    - link "User & Roles":
      - /url: /users
    - option "Booking Portal"
    - option "JaneAI"
    - text: Feedback
    - link "Voting Portal":
      - /url: /voting-portal
  - button "AS Andreas Stadler andreas.stadler@storeroom.at"
  - button
- main:
  - link "Bookings":
    - /url: /bookings
  - text: Booking 2342-4774-4295-138 Active
  - button "Actions"
  - heading "General" [level=3]
  - table:
    - rowgroup:
      - row "Customer Emmy Bradtke":
        - rowheader "Customer"
        - cell "Emmy Bradtke":
          - link "Emmy Bradtke":
            - /url: /customers/854197681
      - row "Location Vienna South":
        - rowheader "Location"
        - cell "Vienna South":
          - link "Vienna South":
            - /url: /locations/5000500050
      - row "Created at 15 Aug 2026":
        - rowheader "Created at"
        - cell "15 Aug 2026"
      - row "Move-in 15 Aug 2026":
        - rowheader "Move-in"
        - cell "15 Aug 2026"
      - row "Move-out -":
        - rowheader "Move-out"
        - cell "-"
      - row "Cancelled at -":
        - rowheader "Cancelled at"
        - cell "-"
      - row "Deposit excl. VAT -":
        - rowheader "Deposit excl. VAT"
        - cell "-"
      - row "Discount -":
        - rowheader "Discount"
        - cell "-"
      - row "Contract -":
        - rowheader "Contract"
        - cell "-"
  - heading "Billing" [level=3]
  - table:
    - rowgroup:
      - row "Booking Plan Basic (1 month)":
        - rowheader "Booking Plan"
        - cell "Basic (1 month)"
      - row "Current period 15 Aug - 15 Sep 2026":
        - rowheader "Current period"
        - cell "15 Aug - 15 Sep 2026"
      - row "Amount excl. VAT €11,000.00":
        - rowheader "Amount excl. VAT"
        - cell "€11,000.00"
      - row "Price adjustment -":
        - rowheader "Price adjustment"
        - cell "-"
      - row "Next invoice 15 Sep 2026 Show preview":
        - rowheader "Next invoice"
        - cell "15 Sep 2026 Show preview":
          - text: 15 Sep 2026
          - link "Show preview":
            - /url: /bookings/234247744295138/upcoming-invoice
      - row "Payment method -":
        - rowheader "Payment method"
        - cell "-"
      - row "Payment option Automatic payment through Stripe":
        - rowheader "Payment option"
        - cell "Automatic payment through Stripe"
  - heading "Notes" [level=3]
  - link:
    - /url: /bookings/234247744295138/edit/notes
  - table:
    - rowgroup:
      - row "Note -":
        - rowheader "Note"
        - cell "-"
  - heading "Items" [level=3]
  - link "Oriental Box uQEYsh":
    - /url: /unit-types/164705268
  - text: /
  - link "Unit OPpVsS":
    - /url: /units/1544029897
  - text: €11,000.00
  - strong: Total excl. VAT
  - strong: €11,000.00
  - text: VAT €1,870.00
  - strong: Total incl. VAT
  - strong: €12,870.00
  - heading "Invoices" [level=3]
  - progressbar:
    - img
  - button "Select all"
  - button "Mark as paid" [disabled]
  - button "SEPA XML actions" [disabled]
  - button:
    - img
  - table:
    - rowgroup:
      - row "Number Status Payment option Due date Unit Discount Total (incl. VAT) Amount due Issue date Actions":
        - columnheader "Number":
          - button "Number"
        - columnheader "Status":
          - button "Status"
        - columnheader "Payment option":
          - button "Payment option"
        - columnheader "Due date":
          - button "Due date"
        - columnheader "Unit":
          - button "Unit"
        - columnheader "Discount"
        - columnheader "Total (incl. VAT)":
          - button "Total (incl. VAT)"
        - columnheader "Amount due":
          - button "Amount due"
        - columnheader "Issue date":
          - button "Issue date"
        - columnheader "Actions"
      - row:
        - columnheader
    - rowgroup:
      - row "No data yet":
        - cell "No data yet"
  - text: "Items per page:"
  - combobox:
    - text: "10"
    - combobox "Items per page:": "10"
  - text: 0-0 of 0
  - button [disabled]
  - button [disabled]
  - button [disabled]
  - button [disabled]
  - heading "Payments" [level=3]
  - progressbar:
    - img
  - table:
    - rowgroup:
      - row "Total Status Invoice no. Date Payment method":
        - columnheader "Total":
          - button "Total"
        - columnheader "Status":
          - button "Status"
        - columnheader "Invoice no.":
          - button "Invoice no."
        - columnheader "Date":
          - button "Date"
        - columnheader "Payment method":
          - button "Payment method"
      - row:
        - columnheader
    - rowgroup:
      - row "No data yet":
        - cell "No data yet"
  - text: "Items per page:"
  - combobox:
    - text: "10"
    - combobox "Items per page:": "10"
  - text: 0-0 of 0
  - button [disabled]
  - button [disabled]
  - button [disabled]
  - button [disabled]
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
- tooltip
```

# Test source

```ts
  892  |   // Reloads, so run last: the deposit field links its amount to the upfront deposit invoice.
  893  |   await test.step('verify deposit on details page', () => verifyBookingDepositInvoiceLink(detailsPage, depositAmount));
  894  | });
  895  | 
  896  | test.fixme('issues only a deposit invoice for a scheduled upfront-deposit booking', async ({
  897  |   createCustomer,
  898  |   createUnitType,
  899  |   createUnit,
  900  |   createDeposit,
  901  |   bookingCreateDialog,
  902  |   trackBookingForTeardown,
  903  | }) => {
  904  |   const customer = await createCustomer(getCustomerCreateData());
  905  |   const deposit = await createDeposit(getDepositCreateData());
  906  |   const unitType = await createUnitType(getUnitTypeCreateData({ deposit }));
  907  |   const unit = await createUnit(getUnitCreateData(unitType));
  908  |   const data = getBookingCreateData(
  909  |     { customer, unitType, unit, deposit },
  910  |     { chargeDepositUpfront: true, moveInDaysInTheFuture: 10 }
  911  |   );
  912  |   const depositAmount = formatCurrency(deposit.priceExclVat, data.location.currency);
  913  |   const today = formatDate(new Date(), data.location.timezone);
  914  | 
  915  |   await bookingCreateDialog.goto();
  916  | 
  917  |   const detailsPage = await test.step('create booking', () => bookingCreateDialog.create(data));
  918  | 
  919  |   trackBookingForTeardown(detailsPage.getBookingId());
  920  | 
  921  |   await test.step('verify booking invoices', async () => {
  922  |     // scheduled, so no first-period invoice yet — only the upfront deposit invoice
  923  |     await verifyBookingInvoiceCount(detailsPage, 1);
  924  | 
  925  |     // the upfront-deposit invoice is not tied to a unit, so its unit cell is left empty
  926  |     await verifyBookingInvoice(
  927  |       detailsPage,
  928  |       {
  929  |         status: 'Open',
  930  |         paymentOption: 'Manual',
  931  |         amount: depositAmount,
  932  |         amountDue: depositAmount,
  933  |         issueDate: today,
  934  |         dueDate: formatDate(getFutureDate(data.location.invoiceDaysUntilDue, 'day'), data.location.timezone),
  935  |       },
  936  |       'Deposit'
  937  |     );
  938  |   });
  939  | 
  940  |   await test.step('verify booking payments', async () => {
  941  |     await verifyBookingPaymentCount(detailsPage, 1);
  942  | 
  943  |     await verifyBookingPayment(
  944  |       detailsPage,
  945  |       { amount: depositAmount, status: 'Not paid yet', date: today },
  946  |       await getBookingDepositInvoiceNumber(detailsPage.invoicesCard.dataTable)
  947  |     );
  948  |   });
  949  | 
  950  |   // Reloads, so run last: the deposit field links its amount to the upfront deposit invoice.
  951  |   await test.step('verify deposit on details page', () => verifyBookingDepositInvoiceLink(detailsPage, depositAmount));
  952  | });
  953  | 
  954  | test('rejects a sepa booking over the payment amount limit', async ({
  955  |   createCustomer,
  956  |   createUnitType,
  957  |   createUnit,
  958  |   bookingCreateDialog,
  959  | }) => {
  960  |   const customer = await createCustomer(getCustomerCreateData());
  961  |   const unitType = await createUnitType(
  962  |     getUnitTypeCreateData({
  963  |       bookingPlans: [
  964  |         {
  965  |           period: 'monthly',
  966  |           amount: 1,
  967  |           priceExclVat: 11000,
  968  |           discount: undefined,
  969  |           publish: true,
  970  |           name: 'Basic',
  971  |           shortDescription: { EN: 'Basic description' },
  972  |         },
  973  |       ],
  974  |     })
  975  |   );
  976  |   const unit = await createUnit(getUnitCreateData(unitType));
  977  |   // a sepa subscription over the SEPA per-transaction limit is rejected on submit with an error snackbar
  978  |   // (no booking is created, so nothing to tear down).
  979  |   const data = getBookingCreateData(
  980  |     { customer, unitType, unit },
  981  |     { paymentOption: 'charge_automatically', paymentMethod: getDefaultSepaPayment() }
  982  |   );
  983  | 
  984  |   await bookingCreateDialog.goto();
  985  | 
  986  |   await test.step('submit booking', async () => {
  987  |     await bookingCreateDialog.fill(data);
  988  |     await bookingCreateDialog.submit();
  989  |   });
  990  | 
  991  |   await test.step('verify the payment limit error', async () => {
> 992  |     await expect(bookingCreateDialog.paymentLimitSnackbar).toBeVisible();
       |                                                            ^ Error: expect(locator).toBeVisible() failed
  993  |   });
  994  | });
  995  | 
  996  | test('rejects a booking without all required fields', async ({ bookingCreateDialog }) => {
  997  |   await bookingCreateDialog.goto();
  998  | 
  999  |   await test.step('submit invalid booking create form', () => bookingCreateDialog.submit());
  1000 | 
  1001 |   await test.step('verify errors on form', async () => {
  1002 |     await expect(bookingCreateDialog.errors).toHaveCountGreaterThan(0);
  1003 |   });
  1004 | });
  1005 | 
```