diff --git a/addon/controllers/billing/invoices/index/new.js b/addon/controllers/billing/invoices/index/new.js index 1758b58..2a1895f 100644 --- a/addon/controllers/billing/invoices/index/new.js +++ b/addon/controllers/billing/invoices/index/new.js @@ -51,14 +51,12 @@ export default class BillingInvoicesIndexNewController extends Controller { defaults.terms = invoiceSettings.default_terms; } - // Due date — calculate from today + offset only when the user - // has explicitly saved a non-zero value in Invoice Settings. - // A null/undefined/0 setting means "no default due date" so we - // leave the field empty rather than silently pre-filling 30 days. - const offset = invoiceSettings.due_date_offset_days; - if (offset != null && Number(offset) > 0) { + // Due date — payment_terms_days is canonical; due_date_offset_days + // remains a legacy alias for settings saved by older clients. + const terms = invoiceSettings.payment_terms_days ?? invoiceSettings.due_date_offset_days; + if (terms != null && Number(terms) > 0) { const due = new Date(); - due.setDate(due.getDate() + Number(offset)); + due.setDate(due.getDate() + Number(terms)); defaults.due_date = due; } } diff --git a/addon/templates/settings/accounting.hbs b/addon/templates/settings/accounting.hbs index 33d5f75..dfb0c21 100644 --- a/addon/templates/settings/accounting.hbs +++ b/addon/templates/settings/accounting.hbs @@ -147,8 +147,7 @@ /> - + - \ No newline at end of file diff --git a/addon/templates/settings/invoice.hbs b/addon/templates/settings/invoice.hbs index 4a83429..0725577 100644 --- a/addon/templates/settings/invoice.hbs +++ b/addon/templates/settings/invoice.hbs @@ -109,8 +109,7 @@ /> - + - \ No newline at end of file diff --git a/addon/templates/settings/payment.hbs b/addon/templates/settings/payment.hbs index f9ddfc9..888528b 100644 --- a/addon/templates/settings/payment.hbs +++ b/addon/templates/settings/payment.hbs @@ -80,8 +80,7 @@ /> - + - \ No newline at end of file diff --git a/composer.json b/composer.json index 3098211..49214ee 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "fleetbase/ledger-api", - "version": "0.0.6", + "version": "0.0.7", "description": "Accounting & Invoicing Extension for Fleetbase", "keywords": [ "fleetbase", diff --git a/docker/taler/README.md b/docker/taler/README.md index 5502f9c..21ddcef 100644 --- a/docker/taler/README.md +++ b/docker/taler/README.md @@ -68,15 +68,30 @@ To seed for a specific company: docker compose exec -e TALER_DEMO_COMPANY_UUID= application php artisan db:seed --class="Fleetbase\\Ledger\\Seeders\\Testing\\TalerDemoSeeder" ``` -The seeder creates an idempotent FleetOps-style payload, order, service quote, -purchase rate, tracking number, core transaction, transaction items, and sent -Ledger invoice in `KUDOS`. The order should appear in FleetOps Orders as -`TALER-DEMO-KUDOS`. Open the seeded public payment link shown by the seeder: +The default demo invoice amount is `KUDOS 0.50`. To seed a specific invoice +amount, use a decimal `KUDOS` value: + +```sh +docker compose exec -e TALER_DEMO_COMPANY_UUID= -e TALER_DEMO_AMOUNT=5.00 application php artisan db:seed --class="Fleetbase\\Ledger\\Seeders\\Testing\\TalerDemoSeeder" +``` + +By default, each seeder run creates a fresh payable FleetOps-style payload, +order, service quote, purchase rate, tracking number, core transaction, +transaction items, and sent Ledger invoice in `KUDOS`. This lets you repeat the +wallet checkout flow without reusing a Taler order that has already been paid. +The order should appear in FleetOps Orders as `TALER-DEMO-KUDOS-`. +Open the seeded public payment link shown by the seeder: ```txt /~/invoice?id= ``` +To intentionally update the same demo fixture, provide a stable run id: + +```sh +docker compose exec -e TALER_DEMO_COMPANY_UUID= -e TALER_DEMO_RUN_ID=nlnet-demo-001 application php artisan db:seed --class="Fleetbase\\Ledger\\Seeders\\Testing\\TalerDemoSeeder" +``` + ## Wallet notes The local bank suggests the local exchange to wallets. To add KUDOS to the GNU diff --git a/docker/taler/init-instance.sh b/docker/taler/init-instance.sh index 53d49ff..873d5a0 100644 --- a/docker/taler/init-instance.sh +++ b/docker/taler/init-instance.sh @@ -133,7 +133,7 @@ webhook_payload="$(jq -n \ url: $url, http_method: "POST", header_template: "Content-Type: application/json", - body_template: "{\"order_id\":\"${order_id}\",\"event_type\":\"pay\"}" + body_template: "{\"order_id\":\"${ORDER_ID}\",\"event_type\":\"pay\"}" }')" webhook_response="$(api POST "/instances/${INSTANCE_ID}/private/webhooks" "${webhook_payload}" "${auth_header}")" diff --git a/extension.json b/extension.json index 7149bc0..56ce98f 100644 --- a/extension.json +++ b/extension.json @@ -1,6 +1,6 @@ { "name": "Ledger", - "version": "0.0.6", + "version": "0.0.7", "description": "Accounting & Invoicing Extension for Fleetbase", "repository": "https://github.com/fleetbase/ledger", "license": "AGPL-3.0-or-later", diff --git a/package.json b/package.json index 3b412ec..d481bca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fleetbase/ledger-engine", - "version": "0.0.6", + "version": "0.0.7", "description": "Accounting & Invoicing Extension for Fleetbase", "keywords": [ "fleetbase-extension", @@ -44,8 +44,8 @@ }, "dependencies": { "@babel/core": "^7.23.2", - "@fleetbase/ember-core": "^0.3.22", - "@fleetbase/ember-ui": "^0.3.38", + "@fleetbase/ember-core": "^0.3.24", + "@fleetbase/ember-ui": "^0.3.39", "@fleetbase/fleetops-data": "^0.1.37", "@fortawesome/ember-fontawesome": "^2.0.0", "@fortawesome/fontawesome-svg-core": "6.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2ad504..4d2be97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,13 @@ importers: dependencies: '@babel/core': specifier: ^7.23.2 - version: 7.23.2 + version: 7.29.0 '@fleetbase/ember-core': - specifier: ^0.3.22 - version: 0.3.22(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(eslint@8.52.0)(webpack@5.89.0) + specifier: ^0.3.24 + version: 0.3.24(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(eslint@8.52.0)(webpack@5.89.0) '@fleetbase/ember-ui': - specifier: ^0.3.38 - version: 0.3.38(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(postcss@8.5.8)(rollup@2.79.1)(tracked-built-ins@3.4.0(@babel/core@7.23.2))(webpack@5.89.0) + specifier: ^0.3.39 + version: 0.3.39(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(postcss@8.5.8)(rollup@2.79.1)(tracked-built-ins@3.4.0(@babel/core@7.29.0))(webpack@5.89.0) '@fleetbase/fleetops-data': specifier: ^0.1.37 version: 0.1.37(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(eslint@8.52.0)(webpack@5.89.0) @@ -71,13 +71,13 @@ importers: version: 2.0.0 '@ember/test-helpers': specifier: ^3.2.0 - version: 3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + version: 3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) '@embroider/test-setup': specifier: ^3.0.2 version: 3.0.2 '@glimmer/component': specifier: ^1.1.2 - version: 1.1.2(@babel/core@7.23.2) + version: 1.1.2(@babel/core@7.29.0) '@glimmer/tracking': specifier: ^1.1.2 version: 1.1.2 @@ -110,7 +110,7 @@ importers: version: 5.0.0 ember-concurrency: specifier: ^4.0.6 - version: 4.0.6(@babel/core@7.23.2) + version: 4.0.6(@babel/core@7.29.0) ember-data: specifier: ^4.12.5 version: 4.12.5(@babel/core@7.23.2)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) @@ -131,10 +131,10 @@ importers: version: 8.0.1(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(qunit@2.20.0) ember-resolver: specifier: ^11.0.1 - version: 11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + version: 11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-source: specifier: ~5.4.0 - version: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + version: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) ember-source-channel-url: specifier: ^3.0.0 version: 3.0.0 @@ -1973,8 +1973,12 @@ packages: resolution: {integrity: sha512-tCYgxJoemUXgjsUztzeJZSwU2ejDp5x2WYI3FsBO55AlcC+mfWm0FsYtuPd9xd9PoO1jZ3T3VyvQQ06HRPtqWw==} engines: {node: '>= 18'} - '@fleetbase/ember-ui@0.3.38': - resolution: {integrity: sha512-8nDYCKSTGtkFk0DQGwrxIljkrp/ANrZk/YOGiyBYSQ20/Uzkn6hciFxrUCUgxMOL511XRPWFdfdXJ6G8uJH0MA==} + '@fleetbase/ember-core@0.3.24': + resolution: {integrity: sha512-WG32JlX4S75ofa34RQEMxFEqc20fTv2Qn3A5+NlqXtL0lfnCthdO+a1DrGqIIierthHl3mVTxhe+z63f8sM6EA==} + engines: {node: '>= 18'} + + '@fleetbase/ember-ui@0.3.39': + resolution: {integrity: sha512-qb8sCq4bfAMq8UGWVlUiXWvRoInmCPqeFu3XDWxUdwJUYR4kGL0lvyO1q2Ej7GcxtiDEnZ4JX+Qp2Tj+TvG3yw==} engines: {node: '>= 18'} '@fleetbase/fleetops-data@0.1.37': @@ -4243,8 +4247,10 @@ packages: decorator-transforms@2.3.1: resolution: {integrity: sha512-PDOk74Zqqy0946Lx4ckXxbgG6uhPScOICtrxL/pXmfznxchqNee0TaJISClGJQe6FeT8ohGqsOgdjfahm4FwEw==} - decorator-transforms@2.3.2: - resolution: {integrity: sha512-XcErcjlmCzG5ODgYjt6ZTXwd6S8fPKln/sJmw15ZXkWG2JpoQNwszis+AwF6XSGlOoG7g8MCEO97g+Yw3fk5OQ==} + decorator-transforms@2.4.0: + resolution: {integrity: sha512-IB+0RqnJpuS7ndH4dVY5dfWTZsrCzN3avWFdjSiET0uT2U24jKywjpVEK97TflnZkZgiSRfmeqc1WfS+1CI23w==} + peerDependencies: + '@babel/core': ^7.23.0 || ^8.0.0 deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} @@ -12486,6 +12492,16 @@ snapshots: - '@babel/core' - supports-color + '@ember/render-modifiers@2.1.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))': + dependencies: + '@embroider/macros': 1.20.0(@babel/core@7.23.2) + ember-cli-babel: 7.26.11 + ember-modifier-manager-polyfill: 1.2.0(@babel/core@7.23.2) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) + transitivePeerDependencies: + - '@babel/core' + - supports-color + '@ember/string@3.1.1': dependencies: ember-cli-babel: 7.26.11 @@ -12523,7 +12539,6 @@ snapshots: - '@glint/template' - supports-color - webpack - optional: true '@ember/test-waiters@3.1.0': dependencies: @@ -12693,22 +12708,32 @@ snapshots: - '@babel/core' - supports-color - '@embroider/util@1.13.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))': + '@embroider/util@1.12.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))': dependencies: '@embroider/macros': 1.20.0(@babel/core@7.23.2) broccoli-funnel: 3.0.8 ember-cli-babel: 7.26.11 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) transitivePeerDependencies: - '@babel/core' - supports-color - '@embroider/util@1.13.5(@babel/core@7.29.0)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))': + '@embroider/util@1.13.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))': + dependencies: + '@embroider/macros': 1.20.0(@babel/core@7.23.2) + broccoli-funnel: 3.0.8 + ember-cli-babel: 7.26.11 + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) + transitivePeerDependencies: + - '@babel/core' + - supports-color + + '@embroider/util@1.13.5(@babel/core@7.29.0)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))': dependencies: '@embroider/macros': 1.20.0(@babel/core@7.29.0) broccoli-funnel: 3.0.8 ember-cli-babel: 7.26.11 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) transitivePeerDependencies: - '@babel/core' - supports-color @@ -12742,12 +12767,12 @@ snapshots: transitivePeerDependencies: - '@typescript-eslint/types' - '@fleetbase/ember-accounting@0.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))': + '@fleetbase/ember-accounting@0.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))': dependencies: '@babel/core': 7.23.2 ember-cli-babel: 8.2.0(@babel/core@7.23.2) ember-cli-htmlbars: 6.3.0 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) transitivePeerDependencies: - supports-color @@ -12784,17 +12809,50 @@ snapshots: - utf-8-validate - webpack - '@fleetbase/ember-ui@0.3.38(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(postcss@8.5.8)(rollup@2.79.1)(tracked-built-ins@3.4.0(@babel/core@7.23.2))(webpack@5.89.0)': + '@fleetbase/ember-core@0.3.24(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(eslint@8.52.0)(webpack@5.89.0)': dependencies: '@babel/core': 7.23.2 - '@ember/render-modifiers': 2.1.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + compress-json: 3.4.0 + date-fns: 2.30.0 + ember-auto-import: 2.8.1(webpack@5.89.0) + ember-can: 6.0.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-inflector@4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-cli-babel: 8.2.0(@babel/core@7.23.2) + ember-cli-htmlbars: 6.3.0 + ember-cli-notifications: 9.1.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-concurrency: 4.0.6(@babel/core@7.23.2) + ember-decorators: 6.1.1 + ember-get-config: 2.1.1(@babel/core@7.23.2) + ember-inflector: 4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-intl: 6.3.2(@babel/core@7.23.2)(webpack@5.89.0) + ember-loading: 2.0.0(@babel/core@7.23.2) + ember-local-storage: 2.0.7(@babel/core@7.23.2) + ember-simple-auth: 6.1.0(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(eslint@8.52.0) + ember-wormhole: 0.6.0 + socketcluster-client: 17.2.2 + transitivePeerDependencies: + - '@ember/string' + - '@ember/test-helpers' + - '@glint/template' + - bufferutil + - ember-resolver + - ember-source + - eslint + - supports-color + - typescript + - utf-8-validate + - webpack + + '@fleetbase/ember-ui@0.3.39(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(postcss@8.5.8)(rollup@2.79.1)(tracked-built-ins@3.4.0(@babel/core@7.29.0))(webpack@5.89.0)': + dependencies: + '@babel/core': 7.23.2 + '@ember/render-modifiers': 2.1.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) '@ember/string': 3.1.1 '@embroider/addon': 0.30.0 '@embroider/macros': 1.20.0(@babel/core@7.23.2) '@event-calendar/core': 5.7.1 - '@fleetbase/ember-accounting': 0.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + '@fleetbase/ember-accounting': 0.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) '@floating-ui/dom': 1.7.6 - '@fortawesome/ember-fontawesome': 2.0.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(rollup@2.79.1)(webpack@5.89.0) + '@fortawesome/ember-fontawesome': 2.0.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(rollup@2.79.1)(webpack@5.89.0) '@fortawesome/fontawesome-svg-core': 6.4.0 '@fortawesome/free-brands-svg-icons': 6.4.0 '@fortawesome/free-solid-svg-icons': 6.4.0 @@ -12827,35 +12885,35 @@ snapshots: chart.js: 4.5.1 chartjs-adapter-date-fns: 3.0.0(chart.js@4.5.1)(date-fns@2.30.0) date-fns: 2.30.0 - ember-animated: 1.1.4(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-animated: 1.1.4(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-auto-import: 2.8.1(webpack@5.89.0) - ember-basic-dropdown: 8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-can: 6.0.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-inflector@4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-basic-dropdown: 8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-can: 6.0.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-inflector@4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-cli-babel: 8.3.1(@babel/core@7.23.2) ember-cli-htmlbars: 6.3.0 ember-cli-postcss: 8.2.0 ember-cli-string-helpers: 6.1.0 ember-composable-helpers: 5.0.0 - ember-concurrency: 4.0.6(@babel/core@7.23.2) - ember-drag-sort: 4.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) - ember-file-upload: 8.4.0(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-modifier@4.3.0(@babel/core@7.23.2))(tracked-built-ins@3.4.0(@babel/core@7.23.2))(webpack@5.89.0) + ember-concurrency: 4.0.6(@babel/core@7.29.0) + ember-drag-sort: 4.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + ember-file-upload: 8.4.0(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-modifier@4.3.0(@babel/core@7.23.2))(tracked-built-ins@3.4.0(@babel/core@7.29.0))(webpack@5.89.0) ember-focus-trap: 1.2.0(@babel/core@7.23.2) ember-get-config: 2.1.1(@babel/core@7.23.2) - ember-gridstack: 4.0.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) - ember-inflector: 4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-leaflet: 5.1.3(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(leaflet@1.9.4)(webpack@5.89.0) + ember-gridstack: 4.0.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + ember-inflector: 4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-leaflet: 5.1.3(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(leaflet@1.9.4)(webpack@5.89.0) ember-loading: 2.0.0(@babel/core@7.23.2) - ember-math-helpers: 4.0.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-modifier: 4.3.0(@babel/core@7.23.2) + ember-math-helpers: 4.0.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-modifier: 4.3.0(@babel/core@7.29.0) ember-on-helper: 0.1.0 - ember-power-calendar: 0.18.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-power-select: 8.6.2(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-basic-dropdown@8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-concurrency@4.0.6(@babel/core@7.23.2))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-power-calendar: 0.18.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-power-select: 8.6.2(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-basic-dropdown@8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-concurrency@4.0.6(@babel/core@7.23.2))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-ref-bucket: 4.1.0(@babel/core@7.23.2) ember-responsive: 5.0.0 ember-style-modifier: 3.1.1(@babel/core@7.23.2)(@ember/string@3.1.1)(webpack@5.89.0) ember-tag-input: 3.1.0 - ember-truth-helpers: 4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-window-mock: 0.9.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-truth-helpers: 4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-window-mock: 0.9.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-wormhole: 0.6.0 gridstack: 7.3.0 imask: 6.6.3 @@ -12993,6 +13051,32 @@ snapshots: - supports-color - webpack + '@fortawesome/ember-fontawesome@2.0.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(rollup@2.79.1)(webpack@5.89.0)': + dependencies: + '@fortawesome/fontawesome-svg-core': 6.4.0 + '@rollup/plugin-node-resolve': 15.2.3(rollup@2.79.1) + array-unique: 0.3.2 + broccoli-file-creator: 2.1.1 + broccoli-merge-trees: 4.2.0 + broccoli-plugin: 4.0.7 + broccoli-rollup: 5.0.0 + broccoli-source: 3.0.1 + camel-case: 4.1.2 + ember-ast-helpers: 0.4.0 + ember-auto-import: 2.8.1(webpack@5.89.0) + ember-cli-babel: 7.26.11 + ember-cli-htmlbars: 6.3.0 + ember-get-config: 2.1.1(@babel/core@7.23.2) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) + find-yarn-workspace-root: 2.0.0 + glob: 10.3.10 + transitivePeerDependencies: + - '@babel/core' + - '@glint/template' + - rollup + - supports-color + - webpack + '@fortawesome/fontawesome-common-types@6.4.0': {} '@fortawesome/fontawesome-svg-core@6.4.0': @@ -15895,6 +15979,13 @@ snapshots: transitivePeerDependencies: - '@babel/core' + decorator-transforms@1.2.1(@babel/core@7.29.0): + dependencies: + '@babel/plugin-syntax-decorators': 7.29.7(@babel/core@7.29.0) + babel-import-util: 2.1.1 + transitivePeerDependencies: + - '@babel/core' + decorator-transforms@2.3.1(@babel/core@7.23.2): dependencies: '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.23.2) @@ -15909,12 +16000,10 @@ snapshots: transitivePeerDependencies: - '@babel/core' - decorator-transforms@2.3.2(@babel/core@7.23.2): + decorator-transforms@2.4.0(@babel/core@7.29.0): dependencies: - '@babel/plugin-syntax-decorators': 7.29.7(@babel/core@7.23.2) + '@babel/core': 7.29.0 babel-import-util: 3.0.1 - transitivePeerDependencies: - - '@babel/core' deep-extend@0.6.0: {} @@ -16055,15 +16144,15 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - ember-animated@1.1.4(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-animated@1.1.4(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: '@embroider/addon-shim': 1.10.2 '@embroider/macros': 1.20.0(@babel/core@7.23.2) - '@embroider/util': 1.12.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + '@embroider/util': 1.12.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) assert-never: 1.4.0 - ember-element-helper: 0.8.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-element-helper: 0.8.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) optionalDependencies: - '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) transitivePeerDependencies: - '@babel/core' - '@glint/environment-ember-loose' @@ -16220,22 +16309,22 @@ snapshots: - supports-color - webpack - ember-basic-dropdown@8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-basic-dropdown@8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: '@babel/core': 7.29.0 - '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) '@embroider/addon-shim': 1.10.2 '@embroider/macros': 1.20.0(@babel/core@7.29.0) - '@embroider/util': 1.13.5(@babel/core@7.29.0)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - '@glimmer/component': 1.1.2(@babel/core@7.23.2) + '@embroider/util': 1.13.5(@babel/core@7.29.0)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + '@glimmer/component': 1.1.2(@babel/core@7.29.0) '@glimmer/tracking': 1.1.2 decorator-transforms: 2.3.1(@babel/core@7.29.0) ember-element-helper: 0.8.8 - ember-lifeline: 7.0.0(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0)) + ember-lifeline: 7.0.0(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0)) ember-modifier: 4.3.0(@babel/core@7.29.0) - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) ember-style-modifier: 4.5.1(@babel/core@7.29.0)(@ember/string@3.1.1) - ember-truth-helpers: 4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-truth-helpers: 4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) transitivePeerDependencies: - '@ember/string' - '@glint/environment-ember-loose' @@ -16266,18 +16355,6 @@ snapshots: - '@glint/template' - supports-color - ember-can@6.0.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-inflector@4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): - dependencies: - '@ember/string': 3.1.1 - '@embroider/addon-shim': 1.10.2 - decorator-transforms: 2.3.1(@babel/core@7.23.2) - ember-inflector: 4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-resolver: 11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) - transitivePeerDependencies: - - '@babel/core' - - supports-color - ember-can@6.0.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-inflector@4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: '@ember/string': 3.1.1 @@ -16930,6 +17007,22 @@ snapshots: - supports-color - webpack + ember-composability-tools@1.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0): + dependencies: + '@babel/core': 7.23.2 + '@ember/render-modifiers': 2.1.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + '@glimmer/component': 1.1.2(@babel/core@7.23.2) + ember-auto-import: 2.8.1(webpack@5.89.0) + ember-cli-babel: 8.2.0(@babel/core@7.23.2) + ember-cli-htmlbars: 6.3.0 + ember-element-helper: 0.8.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) + transitivePeerDependencies: + - '@glint/environment-ember-loose' + - '@glint/template' + - supports-color + - webpack + ember-composable-helpers@5.0.0: dependencies: '@babel/core': 7.23.2 @@ -16983,6 +17076,17 @@ snapshots: - '@babel/core' - supports-color + ember-concurrency@4.0.6(@babel/core@7.29.0): + dependencies: + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + '@babel/types': 7.29.7 + '@embroider/addon-shim': 1.10.2 + decorator-transforms: 1.2.1(@babel/core@7.29.0) + transitivePeerDependencies: + - '@babel/core' + - supports-color + ember-cookies@1.3.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: '@embroider/addon-shim': 1.10.2 @@ -17042,26 +17146,26 @@ snapshots: - '@babel/core' - supports-color - ember-drag-sort@4.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0): + ember-drag-sort@4.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0): dependencies: '@babel/core': 7.29.0 ember-auto-import: 2.12.1(webpack@5.89.0) ember-cli-babel: 8.2.0(@babel/core@7.29.0) ember-cli-htmlbars: 6.3.0 ember-element-helper: 0.8.8 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) ember-template-imports: 4.4.0 transitivePeerDependencies: - '@glint/template' - supports-color - webpack - ember-element-helper@0.6.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-element-helper@0.6.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: - '@embroider/util': 1.12.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + '@embroider/util': 1.12.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-cli-babel: 7.26.11 ember-cli-htmlbars: 6.3.0 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) transitivePeerDependencies: - '@babel/core' - '@glint/environment-ember-loose' @@ -17079,6 +17183,17 @@ snapshots: - '@glint/template' - supports-color + ember-element-helper@0.8.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): + dependencies: + '@embroider/addon-shim': 1.8.3 + '@embroider/util': 1.12.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) + transitivePeerDependencies: + - '@babel/core' + - '@glint/environment-ember-loose' + - '@glint/template' + - supports-color + ember-element-helper@0.8.8: dependencies: '@embroider/addon-shim': 1.10.2 @@ -17109,17 +17224,17 @@ snapshots: - '@glint/template' - supports-color - ember-file-upload@8.4.0(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-modifier@4.3.0(@babel/core@7.23.2))(tracked-built-ins@3.4.0(@babel/core@7.23.2))(webpack@5.89.0): + ember-file-upload@8.4.0(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-modifier@4.3.0(@babel/core@7.23.2))(tracked-built-ins@3.4.0(@babel/core@7.29.0))(webpack@5.89.0): dependencies: - '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) '@ember/test-waiters': 3.1.0 '@embroider/addon-shim': 1.10.2 '@embroider/macros': 1.20.0(@babel/core@7.23.2) - '@glimmer/component': 1.1.2(@babel/core@7.23.2) + '@glimmer/component': 1.1.2(@babel/core@7.29.0) '@glimmer/tracking': 1.1.2 ember-auto-import: 2.8.1(webpack@5.89.0) - ember-modifier: 4.3.0(@babel/core@7.23.2) - tracked-built-ins: 3.4.0(@babel/core@7.23.2) + ember-modifier: 4.3.0(@babel/core@7.29.0) + tracked-built-ins: 3.4.0(@babel/core@7.29.0) transitivePeerDependencies: - '@babel/core' - '@glint/template' @@ -17135,12 +17250,12 @@ snapshots: - '@babel/core' - supports-color - ember-functions-as-helper-polyfill@2.1.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-functions-as-helper-polyfill@2.1.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: ember-cli-babel: 7.26.11 ember-cli-typescript: 5.2.1 ember-cli-version-checker: 5.1.2 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) transitivePeerDependencies: - supports-color @@ -17153,14 +17268,14 @@ snapshots: - '@glint/template' - supports-color - ember-gridstack@4.0.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0): + ember-gridstack@4.0.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0): dependencies: - '@ember/render-modifiers': 2.1.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + '@ember/render-modifiers': 2.1.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-auto-import: 2.8.1(webpack@5.89.0) ember-cli-babel: 7.26.11 ember-cli-htmlbars: 6.3.0 - ember-modifier: 4.3.0(@babel/core@7.23.2) - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-modifier: 4.3.0(@babel/core@7.29.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) gridstack: 7.3.0 transitivePeerDependencies: - '@babel/core' @@ -17247,7 +17362,7 @@ snapshots: - supports-color - webpack - ember-leaflet@5.1.3(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(leaflet@1.9.4)(webpack@5.89.0): + ember-leaflet@5.1.3(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(leaflet@1.9.4)(webpack@5.89.0): dependencies: '@glimmer/component': 1.1.2(@babel/core@7.23.2) '@glimmer/tracking': 1.1.2 @@ -17255,10 +17370,10 @@ snapshots: broccoli-merge-trees: 4.2.0 ember-cli-babel: 7.26.11 ember-cli-htmlbars: 6.3.0 - ember-composability-tools: 1.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + ember-composability-tools: 1.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) ember-in-element-polyfill: 1.0.1 ember-render-helpers: 0.2.0 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) fastboot-transform: 0.1.3 leaflet: 1.9.4 resolve: 1.22.11 @@ -17269,11 +17384,11 @@ snapshots: - supports-color - webpack - ember-lifeline@7.0.0(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0)): + ember-lifeline@7.0.0(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0)): dependencies: '@embroider/addon-shim': 1.10.2 optionalDependencies: - '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) transitivePeerDependencies: - supports-color @@ -17319,6 +17434,13 @@ snapshots: transitivePeerDependencies: - supports-color + ember-math-helpers@4.0.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): + dependencies: + '@embroider/addon-shim': 1.8.7 + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) + transitivePeerDependencies: + - supports-color + ember-modifier-manager-polyfill@1.2.0(@babel/core@7.23.2): dependencies: ember-cli-babel: 7.26.11 @@ -17339,18 +17461,10 @@ snapshots: - '@babel/core' - supports-color - ember-modifier@4.3.0(@babel/core@7.23.2): - dependencies: - '@embroider/addon-shim': 1.10.2 - decorator-transforms: 2.3.1(@babel/core@7.23.2) - transitivePeerDependencies: - - '@babel/core' - - supports-color - ember-modifier@4.3.0(@babel/core@7.29.0): dependencies: '@embroider/addon-shim': 1.10.2 - decorator-transforms: 2.3.1(@babel/core@7.29.0) + decorator-transforms: 2.3.1(@babel/core@7.23.2) transitivePeerDependencies: - '@babel/core' - supports-color @@ -17367,7 +17481,7 @@ snapshots: transitivePeerDependencies: - supports-color - ember-power-calendar@0.18.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-power-calendar@0.18.0(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: ember-assign-helper: 0.4.0 ember-cli-babel: 7.26.11 @@ -17375,7 +17489,7 @@ snapshots: ember-cli-htmlbars: 6.3.0 ember-concurrency: 2.3.7(@babel/core@7.23.2) ember-decorators: 6.1.1 - ember-element-helper: 0.6.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-element-helper: 0.6.1(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) ember-truth-helpers: 3.1.1 transitivePeerDependencies: - '@babel/core' @@ -17384,21 +17498,21 @@ snapshots: - ember-source - supports-color - ember-power-select@8.6.2(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-basic-dropdown@8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-concurrency@4.0.6(@babel/core@7.23.2))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-power-select@8.6.2(@babel/core@7.23.2)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-basic-dropdown@8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)))(ember-concurrency@4.0.6(@babel/core@7.23.2))(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: - '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) + '@ember/test-helpers': 3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0) '@embroider/addon-shim': 1.10.2 - '@embroider/util': 1.13.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - '@glimmer/component': 1.1.2(@babel/core@7.23.2) + '@embroider/util': 1.13.5(@babel/core@7.23.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + '@glimmer/component': 1.1.2(@babel/core@7.29.0) '@glimmer/tracking': 1.1.2 decorator-transforms: 2.3.1(@babel/core@7.23.2) ember-assign-helper: 0.5.1 - ember-basic-dropdown: 8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.23.2))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-concurrency: 4.0.6(@babel/core@7.23.2) - ember-lifeline: 7.0.0(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0)) - ember-modifier: 4.3.0(@babel/core@7.23.2) - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) - ember-truth-helpers: 4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-basic-dropdown: 8.4.0(@ember/string@3.1.1)(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0))(@glimmer/component@1.1.2(@babel/core@7.29.0))(@glimmer/tracking@1.1.2)(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-concurrency: 4.0.6(@babel/core@7.29.0) + ember-lifeline: 7.0.0(@ember/test-helpers@3.2.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0))(webpack@5.89.0)) + ember-modifier: 4.3.0(@babel/core@7.29.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) + ember-truth-helpers: 4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) transitivePeerDependencies: - '@babel/core' - '@glint/environment-ember-loose' @@ -17445,14 +17559,6 @@ snapshots: transitivePeerDependencies: - supports-color - ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): - dependencies: - ember-cli-babel: 7.26.11 - optionalDependencies: - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) - transitivePeerDependencies: - - supports-color - ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: ember-cli-babel: 7.26.11 @@ -17616,7 +17722,7 @@ snapshots: '@ember/string': 3.1.1 ember-auto-import: 2.8.1(webpack@5.89.0) ember-cli-babel: 7.26.11 - ember-modifier: 4.3.0(@babel/core@7.23.2) + ember-modifier: 4.3.0(@babel/core@7.29.0) transitivePeerDependencies: - '@babel/core' - '@glint/template' @@ -17714,11 +17820,11 @@ snapshots: transitivePeerDependencies: - supports-color - ember-truth-helpers@4.0.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-truth-helpers@4.0.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: '@embroider/addon-shim': 1.10.2 - ember-functions-as-helper-polyfill: 2.1.3(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-functions-as-helper-polyfill: 2.1.3(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) transitivePeerDependencies: - supports-color @@ -17749,11 +17855,11 @@ snapshots: - encoding - supports-color - ember-window-mock@0.9.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + ember-window-mock@0.9.0(ember-source@5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: ember-cli-babel: 7.26.11 ember-cli-htmlbars: 6.3.0 - ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + ember-source: 5.4.0(@babel/core@7.29.0)(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.89.0) transitivePeerDependencies: - supports-color @@ -22330,10 +22436,10 @@ snapshots: tr46@0.0.3: {} - tracked-built-ins@3.4.0(@babel/core@7.23.2): + tracked-built-ins@3.4.0(@babel/core@7.29.0): dependencies: '@embroider/addon-shim': 1.10.3 - decorator-transforms: 2.3.2(@babel/core@7.23.2) + decorator-transforms: 2.4.0(@babel/core@7.29.0) ember-tracked-storage-polyfill: 1.0.1 transitivePeerDependencies: - '@babel/core' diff --git a/server/seeders/Testing/TalerDemoSeeder.php b/server/seeders/Testing/TalerDemoSeeder.php index 89f6572..6784dc7 100644 --- a/server/seeders/Testing/TalerDemoSeeder.php +++ b/server/seeders/Testing/TalerDemoSeeder.php @@ -13,6 +13,7 @@ use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Str; use Milon\Barcode\Facades\DNS2DFacade as DNS2D; class TalerDemoSeeder extends Seeder @@ -21,11 +22,14 @@ class TalerDemoSeeder extends Seeder private const SEED = 'taler_demo'; private const CURRENCY = 'KUDOS'; - private const AMOUNT = 50; - private const BASE_AMOUNT = 40; - private const FEE_AMOUNT = 10; + private const DEFAULT_AMOUNT = '0.50'; private array $ids = []; + private string $seedRunId = ''; + private string $seedRunSuffix = ''; + private int $amount = 50; + private int $baseAmount = 40; + private int $feeAmount = 10; public function run(): void { @@ -38,8 +42,14 @@ public function run(): void } session(['company' => $company->uuid]); - $this->ids = $this->stableIds($company->uuid); $now = Carbon::now(); + $this->seedRunId = $this->resolveSeedRunId($now); + $this->seedRunSuffix = $this->seedRunSuffix($this->seedRunId); + $this->ids = $this->stableIds($company->uuid, $this->seedRunId); + + if (!$this->resolveAmount()) { + return; + } DB::transaction(function () use ($company, $now) { $this->seedFleetOpsRoutePlaces($company, $now); @@ -53,10 +63,13 @@ public function run(): void $publicId = $this->invoicePublicId($company->uuid); $orderId = $this->publicId('order', $company->uuid); $this->command?->info("[Ledger/Taler] Seeded KUDOS demo invoice {$publicId} for company {$company->public_id}."); - $this->command?->info("[Ledger/Taler] FleetOps order: {$orderId} / TALER-DEMO-KUDOS"); + $this->command?->info("[Ledger/Taler] Run ID: {$this->seedRunId}"); + $this->command?->info("[Ledger/Taler] Amount: " . self::CURRENCY . ' ' . $this->formatAmount($this->amount)); + $this->command?->info("[Ledger/Taler] FleetOps order: {$orderId} / {$this->orderInternalId()}"); $this->command?->info("[Ledger/Taler] Public payment link: /~/invoice?id={$publicId}"); $this->command?->info("[Ledger/Taler] Ledger route: /ledger/invoice/{$publicId}"); - $this->command?->info('[Ledger/Taler] Use backend_url=http://taler-merchant.lvh.me:9966 and the generated token from packages/ledger/docker/taler/generated-token.txt.'); + $this->command?->info('[Ledger/Taler] Local gateway: backend_url=http://taler-merchant.lvh.me:9966 and the generated token from packages/ledger/docker/taler/generated-token.txt.'); + $this->command?->info('[Ledger/Taler] Hosted sandbox gateway: backend_url=https://merchant.taler.fleetbase.io, instance_id=default, and the hosted token.'); } protected function resolveCompany(): ?Company @@ -67,25 +80,27 @@ protected function resolveCompany(): ?Company ); } - private function stableIds(string $companyUuid): array + private function stableIds(string $companyUuid, string $seedRunId): array { + $runScope = $companyUuid . ':' . $seedRunId; + return [ 'pickup' => $this->stableUuid($companyUuid . ':pickup'), 'dropoff' => $this->stableUuid($companyUuid . ':dropoff'), - 'payload' => $this->stableUuid($companyUuid . ':payload'), - 'order' => $this->stableUuid($companyUuid . ':order'), - 'tracking_number' => $this->stableUuid($companyUuid . ':tracking-number'), - 'tracking_status' => $this->stableUuid($companyUuid . ':tracking-status-created'), - 'service_quote' => $this->stableUuid($companyUuid . ':service-quote'), - 'quote_item_base' => $this->stableUuid($companyUuid . ':quote-item-base'), - 'quote_item_fee' => $this->stableUuid($companyUuid . ':quote-item-fee'), - 'purchase_rate' => $this->stableUuid($companyUuid . ':purchase-rate'), - 'transaction' => $this->stableUuid($companyUuid . ':transaction'), - 'transaction_base' => $this->stableUuid($companyUuid . ':transaction-item-base'), - 'transaction_fee' => $this->stableUuid($companyUuid . ':transaction-item-fee'), - 'invoice' => $this->stableUuid($companyUuid . ':invoice'), - 'invoice_base' => $this->stableUuid($companyUuid . ':invoice-item-base'), - 'invoice_fee' => $this->stableUuid($companyUuid . ':invoice-item-fee'), + 'payload' => $this->stableUuid($runScope . ':payload'), + 'order' => $this->stableUuid($runScope . ':order'), + 'tracking_number' => $this->stableUuid($runScope . ':tracking-number'), + 'tracking_status' => $this->stableUuid($runScope . ':tracking-status-created'), + 'service_quote' => $this->stableUuid($runScope . ':service-quote'), + 'quote_item_base' => $this->stableUuid($runScope . ':quote-item-base'), + 'quote_item_fee' => $this->stableUuid($runScope . ':quote-item-fee'), + 'purchase_rate' => $this->stableUuid($runScope . ':purchase-rate'), + 'transaction' => $this->stableUuid($runScope . ':transaction'), + 'transaction_base' => $this->stableUuid($runScope . ':transaction-item-base'), + 'transaction_fee' => $this->stableUuid($runScope . ':transaction-item-fee'), + 'invoice' => $this->stableUuid($runScope . ':invoice'), + 'invoice_base' => $this->stableUuid($runScope . ':invoice-item-base'), + 'invoice_fee' => $this->stableUuid($runScope . ':invoice-item-fee'), ]; } @@ -132,7 +147,7 @@ private function seedFleetOpsQuoteFixture(Company $company, Carbon $now): void 'dropoff_uuid' => Schema::hasTable('places') ? $this->ids['dropoff'] : null, 'provider' => 'fleetbase', 'payment_method' => 'taler', - 'cod_amount' => self::AMOUNT, + 'cod_amount' => $this->amount, 'cod_currency' => self::CURRENCY, 'cod_payment_method' => 'taler', 'type' => 'transport', @@ -149,10 +164,10 @@ private function seedFleetOpsQuoteFixture(Company $company, Carbon $now): void [ '_key' => $this->fixtureKey('service_quote'), 'public_id' => $this->publicId('quote', $company->uuid), - 'request_id' => self::SEED, + 'request_id' => $this->seedRunId, 'company_uuid' => $company->uuid, 'payload_uuid' => $this->ids['payload'], - 'amount' => self::AMOUNT, + 'amount' => $this->amount, 'currency' => self::CURRENCY, 'meta' => $this->meta('service_quote', [ 'description' => 'GNU Taler KUDOS demo service quote', @@ -163,8 +178,8 @@ private function seedFleetOpsQuoteFixture(Company $company, Carbon $now): void ] ); - $this->seedServiceQuoteItem('quote_item_base', 'taler-demo-base', 'Taler demo delivery service', self::BASE_AMOUNT, $now); - $this->seedServiceQuoteItem('quote_item_fee', 'taler-demo-fee', 'Taler demo handling fee', self::FEE_AMOUNT, $now); + $this->seedServiceQuoteItem('quote_item_base', 'taler-demo-base', 'Taler demo delivery service', $this->baseAmount, $now); + $this->seedServiceQuoteItem('quote_item_fee', 'taler-demo-fee', 'Taler demo handling fee', $this->feeAmount, $now); } private function seedCoreTransaction(Company $company, Carbon $now): void @@ -183,16 +198,16 @@ private function seedCoreTransaction(Company $company, Carbon $now): void 'subject_type' => 'Fleetbase\\FleetOps\\Models\\Order', 'context_uuid' => $this->ids['purchase_rate'], 'context_type' => 'Fleetbase\\FleetOps\\Models\\PurchaseRate', - 'gateway_transaction_id' => 'taler-demo-' . substr(hash('sha256', $company->uuid), 0, 16), + 'gateway_transaction_id' => 'taler-demo-' . $this->seedRunSuffix, 'gateway' => 'internal', - 'amount' => self::AMOUNT, + 'amount' => $this->amount, 'fee_amount' => 0, 'tax_amount' => 0, - 'net_amount' => self::AMOUNT, + 'net_amount' => $this->amount, 'currency' => self::CURRENCY, 'exchange_rate' => 1, 'description' => 'GNU Taler KUDOS demo dispatch order', - 'reference' => 'taler-demo-' . substr(hash('sha256', $company->uuid), 0, 24), + 'reference' => 'taler-demo-' . $this->seedRunSuffix, 'type' => 'dispatch', 'direction' => 'credit', 'status' => 'success', @@ -206,8 +221,8 @@ private function seedCoreTransaction(Company $company, Carbon $now): void ]) ); - $this->seedTransactionItem('transaction_base', 'taler-demo-base', 'Taler demo delivery service', self::BASE_AMOUNT, 0, $now); - $this->seedTransactionItem('transaction_fee', 'taler-demo-fee', 'Taler demo handling fee', self::FEE_AMOUNT, 1, $now); + $this->seedTransactionItem('transaction_base', 'taler-demo-base', 'Taler demo delivery service', $this->baseAmount, 0, $now); + $this->seedTransactionItem('transaction_fee', 'taler-demo-fee', 'Taler demo handling fee', $this->feeAmount, 1, $now); } private function seedFleetOpsOrderFixture(Company $company, Carbon $now): void @@ -228,7 +243,7 @@ private function seedFleetOpsOrderFixture(Company $company, Carbon $now): void 'public_id' => $this->publicId('rate', $company->uuid), 'meta' => $this->meta('purchase_rate', [ 'currency' => self::CURRENCY, - 'amount' => self::AMOUNT, + 'amount' => $this->amount, ]), 'company_uuid' => $company->uuid, 'transaction_uuid' => Schema::hasTable('transactions') ? $this->ids['transaction'] : null, @@ -245,7 +260,7 @@ private function seedFleetOpsOrderFixture(Company $company, Carbon $now): void $this->columns('orders', [ '_key' => $this->fixtureKey('order'), 'public_id' => $this->publicId('order', $company->uuid), - 'internal_id' => 'TALER-DEMO-KUDOS', + 'internal_id' => $this->orderInternalId(), 'company_uuid' => $company->uuid, 'payload_uuid' => Schema::hasTable('payloads') ? $this->ids['payload'] : null, 'transaction_uuid' => Schema::hasTable('transactions') ? $this->ids['transaction'] : null, @@ -253,7 +268,7 @@ private function seedFleetOpsOrderFixture(Company $company, Carbon $now): void 'order_config_uuid' => $orderConfigUuid, 'meta' => $this->meta('order', [ 'currency' => self::CURRENCY, - 'total' => self::AMOUNT, + 'total' => $this->amount, ]), 'notes' => 'GNU Taler KUDOS demo order for local invoice payment testing.', 'pod_method' => 'scan', @@ -280,10 +295,10 @@ private function seedFleetOpsTrackingFixture(Company $company, Carbon $now): voi 'company_uuid' => $company->uuid, 'owner_uuid' => $this->ids['order'], 'owner_type' => 'Fleetbase\\FleetOps\\Models\\Order', - 'tracking_number' => 'TALER-DEMO-' . strtoupper(substr(hash('sha256', $company->uuid), 0, 10)), + 'tracking_number' => 'TALER-DEMO-' . strtoupper($this->seedRunSuffix), 'region' => 'SG', - 'qr_code' => DNS2D::getBarcodePNG($this->ids['order'], 'QRCODE'), - 'barcode' => DNS2D::getBarcodePNG($this->ids['order'], 'PDF417'), + 'qr_code' => DNS2D::getBarcodePNG($this->orderInternalId(), 'QRCODE'), + 'barcode' => DNS2D::getBarcodePNG($this->orderInternalId(), 'PDF417'), 'created_at' => $now, 'updated_at' => $now, ] @@ -320,11 +335,7 @@ private function seedTrackingStatus(Company $company, Carbon $now): void 'city' => 'Singapore', 'country' => 'SG', 'location' => new Point(1.2816, 103.8510), - 'meta' => [ - 'seed' => self::SEED, - 'seed_id' => 'tracking_status_created', - 'currency' => self::CURRENCY, - ], + 'meta' => $this->metaArray('tracking_status_created'), 'created_at' => $now, 'updated_at' => $now, ])->save(); @@ -391,6 +402,14 @@ private function seedTransactionItem(string $idKey, string $code, string $descri private function seedInvoice(Company $company, Carbon $now): void { $invoicePublicId = $this->invoicePublicId($company->uuid); + $existingInvoice = Invoice::where('uuid', $this->ids['invoice'])->first(); + $isPaidInvoice = $existingInvoice && ($existingInvoice->status === 'paid' || (int) $existingInvoice->amount_paid > 0); + + if ($isPaidInvoice) { + $this->command?->warn("[Ledger/Taler] Run {$this->seedRunId} already has a paid invoice; leaving invoice totals and line items unchanged."); + + return; + } DB::table('ledger_invoices')->updateOrInsert( ['uuid' => $this->ids['invoice']], @@ -400,14 +419,14 @@ private function seedInvoice(Company $company, Carbon $now): void 'company_uuid' => $company->uuid, 'order_uuid' => Schema::hasTable('orders') ? $this->ids['order'] : null, 'transaction_uuid' => Schema::hasTable('transactions') ? $this->ids['transaction'] : null, - 'number' => 'TALER-DEMO-' . strtoupper(substr(hash('sha256', $company->uuid), 0, 8)), + 'number' => $this->invoiceNumber(), 'date' => $now->toDateString(), 'due_date' => $now->copy()->addDays(7)->toDateString(), - 'subtotal' => self::AMOUNT, + 'subtotal' => $this->amount, 'tax' => 0, - 'total_amount' => self::AMOUNT, + 'total_amount' => $this->amount, 'amount_paid' => 0, - 'balance' => self::AMOUNT, + 'balance' => $this->amount, 'currency' => self::CURRENCY, 'status' => 'sent', 'notes' => 'GNU Taler KUDOS demo invoice for local payment testing.', @@ -423,15 +442,16 @@ private function seedInvoice(Company $company, Carbon $now): void ] ); - $this->seedInvoiceItem('invoice_base', 'Taler demo delivery service', self::BASE_AMOUNT, $now); - $this->seedInvoiceItem('invoice_fee', 'Taler demo handling fee', self::FEE_AMOUNT, $now); + $this->seedInvoiceItem('invoice_base', 'Taler demo delivery service', $this->baseAmount, $now); + $this->seedInvoiceItem('invoice_fee', 'Taler demo handling fee', $this->feeAmount, $now); Invoice::where('uuid', $this->ids['invoice'])->first()?->calculateTotals(); + DB::table('ledger_invoices') ->where('uuid', $this->ids['invoice']) ->update([ 'amount_paid' => 0, - 'balance' => self::AMOUNT, + 'balance' => $this->amount, 'status' => 'sent', 'sent_at' => $now, 'updated_at' => $now, @@ -476,11 +496,7 @@ private function upsertPlace(string $idKey, Company $company, array $place, Carb 'latitude' => (string) $place['lat'], 'longitude' => (string) $place['lng'], 'type' => 'address', - 'meta' => [ - 'seed' => self::SEED, - 'seed_id' => $idKey, - 'currency' => self::CURRENCY, - ], + 'meta' => $this->metaArray($idKey, includeRunId: false), 'created_at' => $now, 'updated_at' => $now, ])->save(); @@ -503,6 +519,10 @@ private function stableUuid(string $value): string private function publicId(string $prefix, string $value): string { + if (!str_starts_with($prefix, 'place-')) { + $value .= ':' . $this->seedRunId; + } + return $prefix . '_taler_demo_' . substr(hash('sha256', self::SEED . ':' . $value), 0, 12); } @@ -513,16 +533,105 @@ private function invoicePublicId(string $companyUuid): string private function fixtureKey(string $seedId): string { + if (in_array($seedId, ['pickup', 'dropoff'], true)) { + return self::SEED . ':' . $seedId; + } + + if ($this->seedRunId) { + return self::SEED . ':' . $this->seedRunId . ':' . $seedId; + } + return self::SEED . ':' . $seedId; } private function meta(string $seedId, array $extra = []): string { - return json_encode(array_merge([ + return json_encode($this->metaArray($seedId, $extra)); + } + + private function metaArray(string $seedId, array $extra = [], bool $includeRunId = true): array + { + return array_merge([ 'seed' => self::SEED, 'seed_id' => $seedId, 'currency' => self::CURRENCY, - ], $extra)); + ], $includeRunId && $this->seedRunId ? ['seed_run_id' => $this->seedRunId] : [], $extra); + } + + private function resolveSeedRunId(Carbon $now): string + { + $configured = trim((string) env('TALER_DEMO_RUN_ID', '')); + + if ($configured !== '') { + return $this->sanitizeRunId($configured); + } + + return $this->sanitizeRunId(sprintf( + 'taler_demo_%s_%s', + $now->format('YmdHis'), + Str::lower(Str::random(6)) + )); + } + + private function sanitizeRunId(string $runId): string + { + $runId = preg_replace('/[^A-Za-z0-9_-]+/', '-', $runId) ?: 'taler-demo'; + $runId = trim($runId, '-_'); + + return substr($runId ?: 'taler-demo', 0, 48); + } + + private function resolveAmount(): bool + { + $amount = trim((string) env('TALER_DEMO_AMOUNT', self::DEFAULT_AMOUNT)); + + if (!preg_match('/^\d+(?:\.\d{1,2})?$/', $amount)) { + $this->command?->error('[Ledger/Taler] Invalid TALER_DEMO_AMOUNT. Use a positive decimal amount with up to 2 decimals, for example TALER_DEMO_AMOUNT=5.00.'); + + return false; + } + + $minorUnits = $this->amountToMinorUnits($amount); + + if ($minorUnits <= 0) { + $this->command?->error('[Ledger/Taler] Invalid TALER_DEMO_AMOUNT. Amount must be greater than 0.'); + + return false; + } + + $this->amount = $minorUnits; + $this->baseAmount = intdiv($minorUnits * 80, 100); + $this->feeAmount = $minorUnits - $this->baseAmount; + + return true; + } + + private function amountToMinorUnits(string $amount): int + { + [$units, $fraction] = array_pad(explode('.', $amount, 2), 2, ''); + $fraction = str_pad($fraction, 2, '0'); + + return ((int) $units * 100) + (int) substr($fraction, 0, 2); + } + + private function formatAmount(int $minorUnits): string + { + return sprintf('%d.%02d', intdiv($minorUnits, 100), $minorUnits % 100); + } + + private function seedRunSuffix(string $runId): string + { + return substr(hash('sha256', self::SEED . ':' . $runId), 0, 12); + } + + private function orderInternalId(): string + { + return 'TALER-DEMO-KUDOS-' . strtoupper($this->seedRunSuffix); + } + + private function invoiceNumber(): string + { + return 'TALER-DEMO-' . strtoupper($this->seedRunSuffix); } private function columns(string $tableName, array $values): array diff --git a/server/src/Http/Controllers/Internal/v1/InvoiceController.php b/server/src/Http/Controllers/Internal/v1/InvoiceController.php index db6dc90..eceb4b2 100644 --- a/server/src/Http/Controllers/Internal/v1/InvoiceController.php +++ b/server/src/Http/Controllers/Internal/v1/InvoiceController.php @@ -41,6 +41,7 @@ public function onAfterCreate(Request $request, Invoice $record, array $input): $record->save(); // Recognise revenue now that totals are finalised (Debit AR, Credit Revenue) app(InvoiceService::class)->recogniseRevenue($record); + $record = app(InvoiceService::class)->autoSendOnCreation($record); $record->load(['customer', 'items', 'template']); } diff --git a/server/src/Http/Controllers/Internal/v1/SettingController.php b/server/src/Http/Controllers/Internal/v1/SettingController.php index cdc0f74..95a31f0 100644 --- a/server/src/Http/Controllers/Internal/v1/SettingController.php +++ b/server/src/Http/Controllers/Internal/v1/SettingController.php @@ -44,14 +44,7 @@ public function getInvoiceSettings(): JsonResponse 'default_template_uuid' => null, ]; - $settings = Setting::lookupCompany('ledger.invoice-settings', $defaults); - - // Merge with defaults so new keys are always present - if (is_array($settings)) { - $settings = array_merge($defaults, $settings); - } else { - $settings = $defaults; - } + $settings = $this->normalizeInvoiceSettings(Setting::lookupCompany('ledger.invoice-settings', $defaults), $defaults); // Attach the template name/public_id for display purposes $settings['default_template'] = null; @@ -94,7 +87,7 @@ public function saveInvoiceSettings(Request $request): JsonResponse ]); // Validate that the template UUID belongs to this company (if provided) - $invoiceSettings = $request->input('invoiceSettings', []); + $invoiceSettings = $this->syncInvoicePaymentTerms($request->input('invoiceSettings', [])); if (!empty($invoiceSettings['default_template_uuid'])) { $template = InvoiceTemplate::where('company_uuid', session('company')) ->where(function ($q) use ($invoiceSettings) { @@ -116,7 +109,7 @@ public function saveInvoiceSettings(Request $request): JsonResponse if (!is_array($current)) { $current = []; } - $merged = array_merge($current, $invoiceSettings); + $merged = $this->normalizeInvoiceSettings(array_merge($current, $invoiceSettings)); Setting::configureCompany('ledger.invoice-settings', $merged); @@ -127,6 +120,60 @@ public function saveInvoiceSettings(Request $request): JsonResponse ]); } + /** + * Normalize invoice settings so payment_terms_days is canonical while + * due_date_offset_days remains a synchronized legacy alias. + */ + private function normalizeInvoiceSettings(mixed $settings, array $defaults = []): array + { + if (!is_array($settings)) { + $settings = []; + } + + if (array_key_exists('payment_terms_days', $settings)) { + $terms = $settings['payment_terms_days']; + } elseif (array_key_exists('due_date_offset_days', $settings)) { + $terms = $settings['due_date_offset_days']; + } else { + $terms = $defaults['payment_terms_days'] ?? $defaults['due_date_offset_days'] ?? 30; + } + + $settings = array_merge($defaults, $settings); + + if ($terms !== null) { + $terms = (int) $terms; + } + + $settings['payment_terms_days'] = $terms; + $settings['due_date_offset_days'] = $terms; + + return $settings; + } + + /** + * Synchronize canonical payment terms and legacy offset on incoming partial + * settings without forcing a default over previously saved values. + */ + private function syncInvoicePaymentTerms(array $settings): array + { + if (array_key_exists('payment_terms_days', $settings)) { + $terms = $settings['payment_terms_days']; + } elseif (array_key_exists('due_date_offset_days', $settings)) { + $terms = $settings['due_date_offset_days']; + } else { + return $settings; + } + + if ($terms !== null) { + $terms = (int) $terms; + } + + $settings['payment_terms_days'] = $terms; + $settings['due_date_offset_days'] = $terms; + + return $settings; + } + // ========================================================================= // Payment Settings // ========================================================================= diff --git a/server/src/Models/Invoice.php b/server/src/Models/Invoice.php index b6ac32a..6aef04c 100644 --- a/server/src/Models/Invoice.php +++ b/server/src/Models/Invoice.php @@ -170,13 +170,14 @@ public static function boot(): void } $prefix = data_get($settings, 'invoice_prefix', 'INV'); - // Use null (not 30) as the fallback so we only apply an offset when - // the user has explicitly saved one in Invoice Settings. A missing or - // null value means "no default due date" — we never want to silently - // pre-fill a date the user never asked for. - $dueDateOffset = isset($settings['due_date_offset_days']) - ? (int) $settings['due_date_offset_days'] - : null; + // payment_terms_days is canonical. due_date_offset_days is retained + // as a legacy alias for settings saved by older clients. + $paymentTermsDays = null; + if (isset($settings['payment_terms_days'])) { + $paymentTermsDays = (int) $settings['payment_terms_days']; + } elseif (isset($settings['due_date_offset_days'])) { + $paymentTermsDays = (int) $settings['due_date_offset_days']; + } $defCurrency = data_get($settings, 'default_currency'); $defNotes = data_get($settings, 'default_notes'); $defTerms = data_get($settings, 'default_terms'); @@ -197,12 +198,11 @@ public static function boot(): void } // ── Due date ─────────────────────────────────────────────────────── - // Only derive a due date when the user has explicitly configured a - // non-zero offset in Invoice Settings. When the setting is absent or - // zero we leave due_date null so the form stays empty. - if (empty($invoice->due_date) && $dueDateOffset !== null && $dueDateOffset > 0) { + // Only derive a due date when payment terms are explicitly non-zero. + // Caller-provided due dates are preserved. + if (empty($invoice->due_date) && $paymentTermsDays !== null && $paymentTermsDays > 0) { $baseDate = $invoice->date ?? now(); - $invoice->due_date = Carbon::parse($baseDate)->addDays($dueDateOffset); + $invoice->due_date = Carbon::parse($baseDate)->addDays($paymentTermsDays); } // ── Notes / Terms ────────────────────────────────────────────────── diff --git a/server/src/Services/InvoiceService.php b/server/src/Services/InvoiceService.php index eafe1ff..39e3001 100644 --- a/server/src/Services/InvoiceService.php +++ b/server/src/Services/InvoiceService.php @@ -8,7 +8,9 @@ use Fleetbase\Ledger\Models\InvoiceItem; use Fleetbase\Ledger\Models\Transaction; use Fleetbase\Ledger\Notifications\InvoiceSent; +use Fleetbase\Models\Setting; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Notification; class InvoiceService @@ -42,7 +44,7 @@ public function __construct(LedgerService $ledgerService) */ public function createFromOrder(Order $order, array $options = [], ?object $purchaseRate = null): Invoice { - return DB::transaction(function () use ($order, $options, $purchaseRate) { + $invoice = DB::transaction(function () use ($order, $options, $purchaseRate) { // Resolve currency from options, order meta, or company default $currency = $options['currency'] ?? $order->getMeta('currency') @@ -89,6 +91,8 @@ public function createFromOrder(Order $order, array $options = [], ?object $purc return $invoice; }); + + return $this->autoSendOnCreation($invoice); } /** @@ -116,6 +120,36 @@ public function send(Invoice $invoice): Invoice return $invoice->fresh(['customer', 'items', 'template']); } + /** + * Automatically send newly-created invoices when enabled in Invoice Settings. + * Send failures are logged and never abort invoice creation. + */ + public function autoSendOnCreation(Invoice $invoice): Invoice + { + $settings = Setting::lookupCompany('ledger.invoice-settings', []); + if (!is_array($settings) || !data_get($settings, 'auto_send_on_creation', false)) { + return $invoice; + } + + $originalStatus = $invoice->status; + $originalSentAt = $invoice->sent_at; + + try { + return $this->send($invoice); + } catch (\Throwable $e) { + $invoice->status = $originalStatus; + $invoice->sent_at = $originalSentAt; + $invoice->saveQuietly(); + + Log::channel('ledger')->warning('[Ledger] Invoice auto-send on creation failed.', [ + 'invoice_uuid' => $invoice->uuid, + 'error' => $e->getMessage(), + ]); + + return $invoice->fresh(['customer', 'items', 'template']); + } + } + /** * Resolve the best customer email available on the invoice customer model. */ diff --git a/server/tests/Feature.php b/server/tests/Feature.php index a55e5d7..5d089ad 100644 --- a/server/tests/Feature.php +++ b/server/tests/Feature.php @@ -50,6 +50,57 @@ ->toContain("return response()->json(['error' => \$e->getMessage()], 422);"); }); +test('invoice settings normalize payment terms and legacy due date offset', function () { + $controller = file_get_contents(__DIR__ . '/../src/Http/Controllers/Internal/v1/SettingController.php'); + + expect($controller) + ->toContain('private function normalizeInvoiceSettings') + ->toContain("if (array_key_exists('payment_terms_days', \$settings))") + ->toContain("} elseif (array_key_exists('due_date_offset_days', \$settings))") + ->toContain("\$terms = \$defaults['payment_terms_days'] ?? \$defaults['due_date_offset_days'] ?? 30;") + ->toContain('$settings = array_merge($defaults, $settings);') + ->toContain("\$settings['payment_terms_days'] = \$terms;") + ->toContain("\$settings['due_date_offset_days'] = \$terms;") + ->toContain("\$settings = \$this->normalizeInvoiceSettings(Setting::lookupCompany('ledger.invoice-settings', \$defaults), \$defaults);") + ->toContain('private function syncInvoicePaymentTerms(array $settings): array') + ->toContain("\$invoiceSettings = \$this->syncInvoicePaymentTerms(\$request->input('invoiceSettings', []));") + ->toContain('$merged = $this->normalizeInvoiceSettings(array_merge($current, $invoiceSettings));'); +}); + +test('invoice defaults use payment terms before legacy due date offset', function () { + $model = file_get_contents(__DIR__ . '/../src/Models/Invoice.php'); + $controller = file_get_contents(__DIR__ . '/../../addon/controllers/billing/invoices/index/new.js'); + + expect($model) + ->toContain("if (isset(\$settings['payment_terms_days']))") + ->toContain("\$paymentTermsDays = (int) \$settings['payment_terms_days'];") + ->toContain("} elseif (isset(\$settings['due_date_offset_days']))") + ->toContain("\$paymentTermsDays = (int) \$settings['due_date_offset_days'];") + ->toContain('&& $paymentTermsDays > 0') + ->toContain('addDays($paymentTermsDays)'); + + expect($controller) + ->toContain('const terms = invoiceSettings.payment_terms_days ?? invoiceSettings.due_date_offset_days;') + ->toContain('due.setDate(due.getDate() + Number(terms));'); +}); + +test('invoice auto send on creation is shared and non blocking', function () { + $invoiceController = file_get_contents(__DIR__ . '/../src/Http/Controllers/Internal/v1/InvoiceController.php'); + $invoiceService = file_get_contents(__DIR__ . '/../src/Services/InvoiceService.php'); + + expect($invoiceController) + ->toContain('autoSendOnCreation($record)'); + + expect($invoiceService) + ->toContain('public function autoSendOnCreation(Invoice $invoice): Invoice') + ->toContain("data_get(\$settings, 'auto_send_on_creation', false)") + ->toContain('return $this->send($invoice);') + ->toContain('catch (\\Throwable $e)') + ->toContain('$invoice->saveQuietly();') + ->toContain("Log::channel('ledger')->warning('[Ledger] Invoice auto-send on creation failed.'") + ->toContain('return $this->autoSendOnCreation($invoice);'); +}); + test('order accounting observer preserves seed metadata on storefront sale journal entries', function () { $observer = file_get_contents(__DIR__ . '/../src/Observers/OrderAccountingObserver.php');