celerp 2.3.3__tar.gz → 2.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {celerp-2.3.3 → celerp-2.3.4}/PKG-INFO +1 -1
- {celerp-2.3.3 → celerp-2.3.4}/celerp/gateway/client.py +225 -70
- {celerp-2.3.3 → celerp-2.3.4}/celerp.egg-info/PKG-INFO +1 -1
- {celerp-2.3.3 → celerp-2.3.4}/celerp.egg-info/SOURCES.txt +3 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp.egg-info/scm_file_list.json +13 -0
- celerp-2.3.4/celerp.egg-info/scm_version.json +8 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/doc_projections.py +11 -2
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/routes.py +358 -61
- celerp-2.3.4/default_modules/celerp-docs/tests/test_line_page_patch_truncate.py +245 -0
- celerp-2.3.4/default_modules/celerp-docs/tests/test_list_page_no_full_state.py +151 -0
- celerp-2.3.4/default_modules/celerp-docs/tests/test_list_query_pushdown.py +399 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/first_party.lock.json +1 -1
- {celerp-2.3.3 → celerp-2.3.4}/ui/api_client.py +161 -8
- {celerp-2.3.3 → celerp-2.3.4}/ui/app.py +8 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/shell.py +87 -11
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/am.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/ar.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/de.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/en.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/es.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/fr.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/id.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/it.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/ja.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/pt.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/th.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/locales/vi.json +1 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/documents.py +288 -115
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings.py +6 -2
- celerp-2.3.3/celerp.egg-info/scm_version.json +0 -8
- {celerp-2.3.3 → celerp-2.3.4}/CLA.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/CONTRIBUTING.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/LICENSING.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/MANIFEST.in +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/NOTICE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/README.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/alembic.ini +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/__main__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/batch.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/cleanup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/commands.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/conversations.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/files.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/intent.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/llm.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/memory.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/models.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/page_count.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/quota.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/service.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/ai/tools.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/alembic.ini +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/alembic_config.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/cli.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/compat.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/compute/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/compute/aggregations.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/compute/valuation.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/config.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/base.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/daily_scheduler.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/http.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/images.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/quickbooks.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/registry.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/relay_token.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/shopify.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/sync_runner.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/upsert.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/util.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/webhooks.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/woocommerce.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/connectors/xero.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/constants.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/db.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/embedded_pg.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/events/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/events/engine.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/events/schemas.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/events/types.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/gateway/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/gateway/state.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/importers/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/importers/importer.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/importers/schema.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/inventory_codes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/main.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/middleware.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/README.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/_auto_stamp.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/_data_reconcile.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/_json_compat.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/env.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/script.py.mako +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/a0b1c2d3e4f5_seed_landed_cost_clearing_accounts.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/a1b2c3d4e5f6_add_doc_share_tokens.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/b1c2d3e4f5a6_add_supporter_badges.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/b2c3d4e5f6a7_add_import_batches.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/b3c4d5e6f7a8_expand_role_permissions_to_role_grants.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/bc0d1e2f3a4b_barcode_unique_index.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/c1d2e3f4a5b6_add_marketplace.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/c2d3e4f5a6b7_add_is_sync_to_shopify.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/c4d5e6f7a8b9_account_cash_flow_category.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/c9d8e7f6a5b4_seed_shrinkage_writeoff_account.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/d0e1f2a3b4c5_add_share_token_expiry.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/d2e3f4a5b6c7_add_password_reset_token.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/d5e6f7a8b9c0_rename_fx_rounding_to_fx_difference.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/e3f4a5b6c7d8_add_company_is_active.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/e4f5a6b7c8d9_backfill_connector_idempotency_key.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/e7c9a1b3d5f2_work_center_default_columns.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/f1a2b3c4d5e6_move_accounts_marketplace_to_modules.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/f6a7b8c9d0e1_seed_fx_rounding_account.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/f8a9b0c1d2e3_work_center_default_backfill.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/fd5de461e14e_initial_schema.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/g1h2i3j4k5l6_add_consignment_flag.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/h2i3j4k5l6m7_add_bank_accounts_and_reconciliation.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/j4k5l6m7n8o9_labels_db_persistence.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/k5l6m7n8o9p0_add_reconciliation_v2.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/l6m7n8o9p0q1_add_sync_runs_table.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/m7n8o9p0q1r2_add_connector_configs_and_outbound_queue.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/n8o9p0q1r2s3_backfill_payment_date.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/o9p0q1r2s3t4_backfill_item_price_fields.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/p1q2r3s4t5u6_add_session_registry_and_user_auth_state.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/q2r3s4t5u6v7_add_system_runtime_state.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/r3s4t5u6v7w8_add_projections_company_entity_type_index.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/s4t5u6v7w8x9_drop_user_company_id_role.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/t5u6v7w8x9y0_seed_inventory_sub_accounts.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/u6v7w8x9y0z1_backfill_item_prices_from_attributes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/v7w8x9y0z1a2_backfill_purchase_unit_defaults.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/w8x9y0z1a2b3_backfill_category_unit_defaults.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/x7y8z9a0b1c2_add_projection_created_at.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/y8z9a0b1c2d3_per_company_ledger_idempotency.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/migrations/versions/z9a0b1c2d3e4_work_centers.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/accounting.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/ai.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/auth.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/base.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/company.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/connector_config.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/import_batch.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/ledger.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/marketplace.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/notification.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/projections.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/share.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/supporter.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/models/sync_run.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/api.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/audit.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/demotion.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/importer.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/license.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/loader.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/meta.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/migrations_runner.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/references.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/registry.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/modules/slots.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/notifications/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/notifications/service.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/notifications/sse.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/output/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/output/branding.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/output/doc_print.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/output/pdf.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/output/share_render.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/projections/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/projections/engine.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/projections/handlers/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/projections/handlers/marketplace.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/projections/handlers/scanning.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/projections/handlers/shopify.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/projections/handlers/system.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/auth.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/companies.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/debug.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/doctor.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/events.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/health.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/ledger.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/notifications.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/stars.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/routers/system.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/schemas/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/activity_redaction.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/attachments.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/auth.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/auto_je.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/backup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/backup_export.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/backup_import.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/backup_repo.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/backup_scheduler.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/backup_state.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/cogs_backfill.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/cost_visibility.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/demo.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/dev_release_guard.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/email.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/field_schema.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/fulfill.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/holdings.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/je_keys.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/landed_cost.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/line_measures.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/list_behavior.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/money.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/payments.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/permissions.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/pick.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/pricing.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/relay_share.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/reorder.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/runtime_state.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/session_tracker.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/shipping.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/star_cta.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/status_doc_backfill.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/supporter_badge.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/system_health.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/services/units.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/session_gate.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp/tax_regimes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp.egg-info/dependency_links.txt +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp.egg-info/entry_points.txt +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp.egg-info/requires.txt +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/celerp.egg-info/top_level.txt +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/conftest.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/conftest_support.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/api_setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/csv_parser.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/matcher.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/models.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/projections.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/celerp_accounting/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/balance-sheet.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/cash-flow.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/extended-journal-csv.csv +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/extended-journal-print.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/extended-journal.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/general-ledger.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/journal-csv.csv +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/journal-print.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/journal.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/ledger.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/pnl.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/statement.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/report_goldens/trial-balance.html +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_accounting_banking.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_accounting_banking_routers.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_accounting_gaps.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_accounting_import_idempotency.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_cash_flow.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_financial_reports_ui.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_journal_gl_soa.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_journal_gl_soa_ui.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_reconciliation_v2.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_reports_end_to_end.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-accounting/tests/test_route_permissions.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-admin/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-admin/celerp_admin/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-admin/celerp_admin/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-admin/celerp_admin/setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/celerp_ai/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/celerp_ai/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/celerp_ai/setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/celerp_ai/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/conftest.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_batch.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_cleanup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_conversations.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_coverage_gaps.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_intent.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_llm.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_memory.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_models.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_page_count.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_quota.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_router.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_routes_coverage.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_service.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-ai/tests/test_tools.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-backup/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-backup/celerp_backup/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-backup/celerp_backup/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-backup/celerp_backup/setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/celerp_connectors/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/celerp_connectors/models.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/celerp_connectors/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/conftest.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_compliance.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_connector_correctness.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_connectors.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_credentials_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_images.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_outbound.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_quickbooks.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_rate_limiting.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_shopify.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_wiring.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_woocommerce.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_woocommerce_webhooks.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-connectors/tests/test_xero.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/celerp_contacts/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/celerp_contacts/migrations.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/celerp_contacts/projections.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/celerp_contacts/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/celerp_contacts/services.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-contacts/celerp_contacts/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-dashboard/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-dashboard/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-dashboard/celerp_dashboard/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-dashboard/celerp_dashboard/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-dashboard/celerp_dashboard/setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/api_setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/doc_constants.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/doc_email.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/doc_service.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/models_share.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/routes_payments.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/routes_share.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/sequences.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/taxes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/celerp_docs/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/conftest.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_audits.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_bulk_payment_alloc_lock.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_consolidate_lots.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_cross_lot_settlement.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_freight_je.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_freight_lines.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_fulfill_no_split.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_fulfillment_activity.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_inbound_je_lifecycle.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_inventory_account_reconciliation.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_landed_receive.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_line_delete_persist.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_line_identifier.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_list_concurrency.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_list_outcome_concurrency.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_memo_close.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_memo_close_projection.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_memo_close_review_fixes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_memo_lifecycle_concurrency.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_memo_line_labels.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_memo_unfulfilled_filter.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_payment_void_activity.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_receive_sku_batch.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_send_visibility.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_service_lines.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_sold_label_ordering.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_void_guards.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-docs/tests/test_writeoffs.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/models_import_batch.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/projections.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/routes_attachments.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/routes_scanning.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/services.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/celerp_inventory/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/tests/test_item_recipe_projection.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/tests/test_item_workflow_projection.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-inventory/tests/test_landed_cost_projection.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/am.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/ar.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/de.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/en.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/es.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/fr.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/id.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/it.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/ja.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/pt.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/th.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/locales/vi.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/models.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/presets.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/service.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/celerp_labels/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/requirements.txt +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/tests/test_labels.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-labels/tests/test_labels_module.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/costing.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/expansion.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/labor.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/migrations.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/projection_handler.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/celerp_manufacturing/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/requirements.txt +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_auto_complete_on_finalize.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_bom_removed.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_build_api.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_completion_lock_order.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_item_recipe_api.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_item_workflow_api.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_labor_providers.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_manufacture_from_doc.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_manufacturing.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_manufacturing_import_idempotency.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_manufacturing_module.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_mfg_events.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_phase2_manufacturing_validations.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_production_order.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_recipe_costing.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_recipe_expansion.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_recost_api.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_run_records.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_to_make_allocation.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_where_used.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_work_centers_and_settings.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-manufacturing/tests/test_workflow_time.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/celerp_reports/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/celerp_reports/api_setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/celerp_reports/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/celerp_reports/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/tests/test_reports_full.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-reports/tests/test_reports_unit.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-subscriptions/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-subscriptions/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-subscriptions/celerp_subscriptions/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-subscriptions/celerp_subscriptions/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-subscriptions/celerp_subscriptions/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-subscriptions/tests/test_subscriptions.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-subscriptions/tests/test_subscriptions_ui.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/LICENSE +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/accessory_fashion.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/activewear.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/art_photography.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/audio_equipment.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/bag_handbag.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/banknote.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/beauty_tool.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/bed_bedroom.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/beer.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/beverage_nonalc.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/body_part_auto.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/book.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/bottoms.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/brake_suspension.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/bullion_coin.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/camera.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/colored_stone.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/comic.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/commercial_space.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/component_part.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/confectionery.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/consulting_service.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/decorative_art.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/diamond.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/drawing.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/dress_jumpsuit.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/electrical_auto.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/electrical_component.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/emerald.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/engine_part.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/fastener.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/fertilizer_chemical.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/film_video.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/fine_writing_instrument.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/fluid_lubricant.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/footwear.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/fragrance.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/fresh_food.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/fresh_produce.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/frozen_food.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/gaming_console.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/gold_bullion.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/grain_cereal.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/haircare.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/hand_tool.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/ingredient_bulk.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/interior_part.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/jewelry.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/kitchen_dining.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/laptop.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/lighting.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/livestock_feed.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/makeup.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/measuring_instrument.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/medal_token.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/mineral_specimen.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/mobile_phone.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/music_cd.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/music_vinyl.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/nail.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/numismatic_coin.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/outdoor_furniture.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/outerwear.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/packaged_food.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/painting.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/parking_bay.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/pearl.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/personal_care.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/pipe_plumbing.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/platinum_bullion.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/power_tool.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/print_edition.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/residential_unit.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/rough_gemstone.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/ruby.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/saas_plan.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/safety_ppe.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/sapphire.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/sculpture.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/seating.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/seeds.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/silver_bullion.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/skincare.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/soft_furnishing.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/software_addon.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/software_license.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/spirit.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/storage_furniture.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/swimwear.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/table_desk.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/tablet.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/tire_wheel.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/tops.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/trading_card.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/tv_display.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/video_game.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/watch.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/watch_strap.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/categories/wine.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/agricultural.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/artwork.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/automotive.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/blank.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/books_media.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/coins_precious_metals.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/consulting.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/cosmetics.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/electronics.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/fashion.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/food_beverage.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/furniture.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/gemstones.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/hardware.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/property_rental.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/saas.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/watches.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/presets/wine_spirits.json +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/celerp_verticals/ui_routes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/tests/test_verticals.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/default_modules/celerp-verticals/tests/test_verticals_routers.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/legal/OFFICIAL-COMPONENTS.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/legal/TRADEMARK.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/packaging/winget/Celerp.Celerp.installer.yaml +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/packaging/winget/Celerp.Celerp.locale.en-US.yaml +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/packaging/winget/Celerp.Celerp.yaml +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/packaging/winget/README.md +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/pyproject.toml +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/setup.cfg +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/test_helpers.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/activity.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/attrs.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/backup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/cloud_gate.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/currency.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/files.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/journal.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/notes.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/phone.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/report_kit.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/components/table.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/config.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/i18n.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/marketplace_catalog.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/__init__.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/account.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/accounting.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/accounting_import.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/auth.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/contacts.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/csv_import.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/dashboard.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/docs_import.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/events.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/financial_reports.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/inventory.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/lists_import.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/manufacturing.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/modules_page.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/notifications.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/reconciliation.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/reports.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/search.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_accounting.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_cloud.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_connectors.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_contacts.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_general.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_import.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_inventory.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_manufacturing.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_payments.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_purchasing.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/settings_sales.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/setup.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/stars.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/subscriptions.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/routes/subscriptions_import.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/security.py +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/app.css +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/htmx.min.js +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/icon.png +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/logo.png +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/vendor/intl-tel-input/img/flags.webp +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/vendor/intl-tel-input/img/flags@2x.webp +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/vendor/intl-tel-input/intlTelInput.min.css +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/vendor/intl-tel-input/intlTelInput.min.js +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/vendor/intl-tel-input/intlTelInputWithUtils.min.js +0 -0
- {celerp-2.3.3 → celerp-2.3.4}/ui/static/vendor/intl-tel-input/utils.js +0 -0
|
@@ -26,7 +26,6 @@ from websockets.exceptions import ConnectionClosed
|
|
|
26
26
|
|
|
27
27
|
log = logging.getLogger(__name__)
|
|
28
28
|
|
|
29
|
-
_PING_INTERVAL = 30 # seconds
|
|
30
29
|
_BACKOFF_MAX = 60 # seconds
|
|
31
30
|
# Consecutive auth rejections before the client stops retrying: a rejected
|
|
32
31
|
# credential never heals on its own, so beyond a small allowance for a
|
|
@@ -37,6 +36,10 @@ _AUTH_FAILED_MAX = 3
|
|
|
37
36
|
# a revoke-then-reshare so it does not flap connect/disconnect).
|
|
38
37
|
_REAP_INTERVAL = 15 * 60 # seconds
|
|
39
38
|
_REAP_GRACE = 5 * 60 # seconds
|
|
39
|
+
# A single websocket send that cannot be handed to the transport within this long means the
|
|
40
|
+
# socket is wedged (a stalled or backpressured peer). Bound every send so it surfaces as an
|
|
41
|
+
# error instead of pinning the proxy task holding a relay slot forever.
|
|
42
|
+
_SEND_DEADLINE = 30 # seconds
|
|
40
43
|
|
|
41
44
|
|
|
42
45
|
def _shop_key(handle: str | None) -> str:
|
|
@@ -85,6 +88,22 @@ class GatewayClient:
|
|
|
85
88
|
# Hold strong refs to fire-and-forget tasks so the loop can't GC them mid-run
|
|
86
89
|
# (a dropped task = a lost proxy response or webhook sync).
|
|
87
90
|
self._bg_tasks: set = set()
|
|
91
|
+
# In-flight proxy tasks keyed by relay request id so an http.cancel frame can
|
|
92
|
+
# abort exactly the one request it names, and no other.
|
|
93
|
+
self._inflight: dict[str, asyncio.Task] = {}
|
|
94
|
+
# Connection generation: bumped on every teardown so a response produced by a
|
|
95
|
+
# request that outlived its socket can be recognised as stale and dropped
|
|
96
|
+
# rather than sent on the freshly rebuilt connection.
|
|
97
|
+
self._generation: int = 0
|
|
98
|
+
# One shared httpx client for all proxied requests, built lazily with bounded
|
|
99
|
+
# connection limits. A fresh client per request opened an unbounded number of
|
|
100
|
+
# pools under load; one bounded client caps the concurrency into the local app.
|
|
101
|
+
self._http_client: Any = None
|
|
102
|
+
# Observability counters for the proxy path, surfaced when the connection ends.
|
|
103
|
+
self._proxied_count = 0
|
|
104
|
+
self._cancelled_count = 0
|
|
105
|
+
self._timeout_count = 0
|
|
106
|
+
self._stale_dropped_count = 0
|
|
88
107
|
# Resolve local server ports for proxy routing.
|
|
89
108
|
# In Electron builds the ports are dynamic; Electron passes them via
|
|
90
109
|
# CELERP_API_PORT / CELERP_UI_PORT env vars so we don't rely on the
|
|
@@ -122,6 +141,22 @@ class GatewayClient:
|
|
|
122
141
|
self._bg_tasks.add(task)
|
|
123
142
|
task.add_done_callback(self._bg_tasks.discard)
|
|
124
143
|
|
|
144
|
+
def _spawn_proxy(self, payload: dict) -> None:
|
|
145
|
+
"""Run a proxied request fire-and-forget, keyed by its relay request id so an
|
|
146
|
+
http.cancel frame can abort exactly that task. The key is cleared when the task
|
|
147
|
+
finishes (a cancel arriving after completion is then a harmless no-op)."""
|
|
148
|
+
request_id = payload.get("id", "")
|
|
149
|
+
task = asyncio.create_task(self._handle_proxy_request(payload))
|
|
150
|
+
self._bg_tasks.add(task)
|
|
151
|
+
self._inflight[request_id] = task
|
|
152
|
+
|
|
153
|
+
def _done(t: asyncio.Task) -> None:
|
|
154
|
+
self._bg_tasks.discard(t)
|
|
155
|
+
if self._inflight.get(request_id) is t:
|
|
156
|
+
del self._inflight[request_id]
|
|
157
|
+
|
|
158
|
+
task.add_done_callback(_done)
|
|
159
|
+
|
|
125
160
|
# ── Public API ─────────────────────────────────────────────────────
|
|
126
161
|
|
|
127
162
|
async def run(self) -> None:
|
|
@@ -198,6 +233,7 @@ class GatewayClient:
|
|
|
198
233
|
await ws.close()
|
|
199
234
|
except Exception:
|
|
200
235
|
pass
|
|
236
|
+
await self._close_http_client()
|
|
201
237
|
|
|
202
238
|
async def _should_reap(self) -> bool:
|
|
203
239
|
"""A free instance with no live share and no recent proxied request should
|
|
@@ -293,40 +329,61 @@ class GatewayClient:
|
|
|
293
329
|
import ssl as _ssl
|
|
294
330
|
_ssl_ctx = _ssl.create_default_context()
|
|
295
331
|
_ssl_ctx.set_alpn_protocols(["http/1.1"])
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
"
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
332
|
+
try:
|
|
333
|
+
async with websockets.connect(
|
|
334
|
+
self._url, ssl=_ssl_ctx, ping_interval=20, ping_timeout=20, max_size=160 * 1024 * 1024
|
|
335
|
+
) as ws:
|
|
336
|
+
self._ws = ws
|
|
337
|
+
# Read current TOS version from config
|
|
338
|
+
from celerp.config import read_config
|
|
339
|
+
cfg = read_config() or {}
|
|
340
|
+
tos_version = cfg.get("cloud", {}).get("tos_version", "")
|
|
341
|
+
# App version: the Electron wrapper passes the release version via
|
|
342
|
+
# CELERP_APP_VERSION; fall back to the package version. Sent on every
|
|
343
|
+
# connect so the handshake reflects the build that is actually running.
|
|
344
|
+
from celerp import __version__ as _pkg_version
|
|
345
|
+
app_version = os.environ.get("CELERP_APP_VERSION") or _pkg_version
|
|
346
|
+
# Send hello handshake
|
|
347
|
+
await self._send(ws, {
|
|
348
|
+
"type": "hello",
|
|
349
|
+
"id": str(uuid.uuid4()),
|
|
350
|
+
"payload": {
|
|
351
|
+
"gateway_token": self._token,
|
|
352
|
+
"instance_id": self._instance_id,
|
|
353
|
+
"tos_version": tos_version,
|
|
354
|
+
"version": app_version,
|
|
355
|
+
},
|
|
356
|
+
})
|
|
357
|
+
# Message dispatch loop
|
|
358
|
+
async for raw in ws:
|
|
359
|
+
try:
|
|
360
|
+
msg = json.loads(raw)
|
|
361
|
+
except json.JSONDecodeError:
|
|
362
|
+
log.warning("Gateway sent non-JSON frame: %r", raw)
|
|
363
|
+
continue
|
|
364
|
+
await self._dispatch(msg)
|
|
365
|
+
finally:
|
|
366
|
+
# Teardown runs on every exit - clean end of the message stream OR an
|
|
367
|
+
# abnormal disconnect raised mid-serve. Kept in a finally so an exception
|
|
368
|
+
# from the async-for can't leave a dangling socket, an unfenced generation,
|
|
369
|
+
# and a stuck status behind.
|
|
370
|
+
self._ws = None
|
|
371
|
+
# A new generation for the next connection: any proxy response still in
|
|
372
|
+
# flight from this socket is now stale and must not be sent on the rebuilt
|
|
373
|
+
# one. Cancel the in-flight proxy tasks that belong to the dead connection -
|
|
374
|
+
# their responses can never be delivered on a socket that no longer exists.
|
|
375
|
+
self._generation += 1
|
|
376
|
+
for task in list(self._inflight.values()):
|
|
377
|
+
if not task.done():
|
|
378
|
+
task.cancel()
|
|
379
|
+
self._inflight.clear()
|
|
380
|
+
log.debug(
|
|
381
|
+
"Gateway proxy activity this connection: proxied=%d cancelled=%d "
|
|
382
|
+
"timed_out=%d stale_dropped=%d",
|
|
383
|
+
self._proxied_count, self._cancelled_count,
|
|
384
|
+
self._timeout_count, self._stale_dropped_count,
|
|
385
|
+
)
|
|
386
|
+
self._set_status("inactive")
|
|
330
387
|
|
|
331
388
|
async def _dispatch(self, msg: dict) -> None:
|
|
332
389
|
msg_type = msg.get("type", "")
|
|
@@ -414,7 +471,13 @@ class GatewayClient:
|
|
|
414
471
|
set_subscription_state(tier, status)
|
|
415
472
|
|
|
416
473
|
elif msg_type == "http.request":
|
|
417
|
-
self.
|
|
474
|
+
self._spawn_proxy(payload)
|
|
475
|
+
|
|
476
|
+
elif msg_type == "http.cancel":
|
|
477
|
+
request_id = payload.get("id", "")
|
|
478
|
+
task = self._inflight.get(request_id)
|
|
479
|
+
if task is not None and not task.done():
|
|
480
|
+
task.cancel()
|
|
418
481
|
|
|
419
482
|
elif msg_type == "shopify.webhook":
|
|
420
483
|
self._spawn(self._handle_shopify_webhook(payload))
|
|
@@ -533,6 +596,31 @@ class GatewayClient:
|
|
|
533
596
|
except Exception as exc:
|
|
534
597
|
log.warning("invoice.payment handling failed (entity=%s): %s", entity_id, exc)
|
|
535
598
|
|
|
599
|
+
def _get_http_client(self):
|
|
600
|
+
"""Return the one shared httpx client used for every proxied request, building
|
|
601
|
+
it lazily on first use. A bounded connection pool caps how many concurrent
|
|
602
|
+
requests this client can drive into the local app, so a burst of relayed
|
|
603
|
+
requests can no longer open an unbounded number of pools. The default timeout
|
|
604
|
+
is the fixed cap; a per-request timeout_ms tightens it further."""
|
|
605
|
+
import httpx
|
|
606
|
+
|
|
607
|
+
if self._http_client is None:
|
|
608
|
+
self._http_client = httpx.AsyncClient(
|
|
609
|
+
timeout=180.0,
|
|
610
|
+
limits=httpx.Limits(max_connections=32, max_keepalive_connections=8),
|
|
611
|
+
)
|
|
612
|
+
return self._http_client
|
|
613
|
+
|
|
614
|
+
async def _close_http_client(self) -> None:
|
|
615
|
+
"""Close the shared httpx client if one was built. Safe to call when none was."""
|
|
616
|
+
client = self._http_client
|
|
617
|
+
self._http_client = None
|
|
618
|
+
if client is not None:
|
|
619
|
+
try:
|
|
620
|
+
await client.aclose()
|
|
621
|
+
except Exception:
|
|
622
|
+
pass
|
|
623
|
+
|
|
536
624
|
async def _handle_proxy_request(self, payload: dict) -> None:
|
|
537
625
|
"""Handle a proxied HTTP request from the relay.
|
|
538
626
|
|
|
@@ -545,10 +633,14 @@ class GatewayClient:
|
|
|
545
633
|
local access.
|
|
546
634
|
"""
|
|
547
635
|
import base64
|
|
548
|
-
import httpx
|
|
549
636
|
|
|
550
637
|
# Activity stamp for the reaper's grace window: any proxied request counts.
|
|
551
638
|
self._last_request_monotonic = time.monotonic()
|
|
639
|
+
self._proxied_count += 1
|
|
640
|
+
# The generation this request belongs to: if the socket is rebuilt before the
|
|
641
|
+
# response is ready, self._generation advances past this and the response is
|
|
642
|
+
# dropped rather than sent on a connection that never issued the request.
|
|
643
|
+
generation = self._generation
|
|
552
644
|
|
|
553
645
|
request_id = payload.get("id", "")
|
|
554
646
|
method = payload.get("method", "GET")
|
|
@@ -557,6 +649,13 @@ class GatewayClient:
|
|
|
557
649
|
headers = payload.get("headers", {})
|
|
558
650
|
body_b64 = payload.get("body_b64", "")
|
|
559
651
|
body = base64.b64decode(body_b64) if body_b64 else None
|
|
652
|
+
# Additive per-request deadline: a numeric timeout_ms bounds this request below
|
|
653
|
+
# the fixed cap so a single slow local handler can't pin a relay slot for 180s.
|
|
654
|
+
# Absent or non-numeric leaves the default cap in force.
|
|
655
|
+
timeout_ms = payload.get("timeout_ms")
|
|
656
|
+
deadline_s: float | None = None
|
|
657
|
+
if isinstance(timeout_ms, (int, float)) and not isinstance(timeout_ms, bool) and timeout_ms > 0:
|
|
658
|
+
deadline_s = timeout_ms / 1000.0
|
|
560
659
|
|
|
561
660
|
# SSE / long-poll paths cannot be proxied over the WS request/response
|
|
562
661
|
# protocol. Return an empty stream so the browser doesn't 500.
|
|
@@ -599,47 +698,98 @@ class GatewayClient:
|
|
|
599
698
|
if query:
|
|
600
699
|
url = f"{url}?{query}"
|
|
601
700
|
|
|
701
|
+
client = self._get_http_client()
|
|
602
702
|
try:
|
|
603
|
-
|
|
703
|
+
if deadline_s is not None:
|
|
704
|
+
# asyncio.wait_for, not asyncio.timeout: the latter is 3.11+, and this package
|
|
705
|
+
# supports Python >=3.10 where it does not exist. wait_for cancels the request and
|
|
706
|
+
# raises TimeoutError on the deadline, which the handler below turns into an error
|
|
707
|
+
# response.
|
|
708
|
+
resp = await asyncio.wait_for(
|
|
709
|
+
client.request(
|
|
710
|
+
method=method,
|
|
711
|
+
url=url,
|
|
712
|
+
headers=headers,
|
|
713
|
+
content=body,
|
|
714
|
+
),
|
|
715
|
+
deadline_s,
|
|
716
|
+
)
|
|
717
|
+
else:
|
|
604
718
|
resp = await client.request(
|
|
605
719
|
method=method,
|
|
606
720
|
url=url,
|
|
607
721
|
headers=headers,
|
|
608
722
|
content=body,
|
|
609
723
|
)
|
|
610
|
-
|
|
611
|
-
#
|
|
612
|
-
#
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
724
|
+
except asyncio.CancelledError:
|
|
725
|
+
# http.cancel aborted this request: emit nothing and let the cancellation
|
|
726
|
+
# propagate so the task is recorded cancelled.
|
|
727
|
+
self._cancelled_count += 1
|
|
728
|
+
raise
|
|
729
|
+
except TimeoutError:
|
|
730
|
+
# The per-request deadline elapsed before the local handler answered. Surface
|
|
731
|
+
# it as an error response instead of hanging to the fixed cap.
|
|
732
|
+
self._timeout_count += 1
|
|
733
|
+
log.warning("Proxy request timed out after %sms for %s %s", timeout_ms, method, path)
|
|
734
|
+
if generation == self._generation:
|
|
735
|
+
await self._send(self._ws, {
|
|
736
|
+
"type": "http.response",
|
|
737
|
+
"payload": {
|
|
738
|
+
"id": request_id,
|
|
739
|
+
"status": 504,
|
|
740
|
+
"headers": [["content-type", "text/plain"]],
|
|
741
|
+
"body_b64": base64.b64encode(b"Local app timed out").decode(),
|
|
742
|
+
},
|
|
743
|
+
})
|
|
744
|
+
else:
|
|
745
|
+
self._stale_dropped_count += 1
|
|
746
|
+
return
|
|
630
747
|
except Exception as exc:
|
|
631
748
|
log.warning("Proxy request failed for %s %s: %s", method, path, exc)
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
"
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
749
|
+
if generation == self._generation:
|
|
750
|
+
await self._send(self._ws, {
|
|
751
|
+
"type": "http.response",
|
|
752
|
+
"payload": {
|
|
753
|
+
"id": request_id,
|
|
754
|
+
"status": 502,
|
|
755
|
+
"headers": [["content-type", "text/plain"]],
|
|
756
|
+
"body_b64": base64.b64encode(
|
|
757
|
+
f"Local app error: {type(exc).__name__}: {exc}".encode()
|
|
758
|
+
).decode(),
|
|
759
|
+
},
|
|
760
|
+
})
|
|
761
|
+
else:
|
|
762
|
+
self._stale_dropped_count += 1
|
|
763
|
+
return
|
|
764
|
+
|
|
765
|
+
# The socket that carried this request may have been rebuilt while it was in
|
|
766
|
+
# flight. A response from a superseded generation belongs to a connection the
|
|
767
|
+
# relay no longer has; sending it on the new socket would answer the wrong
|
|
768
|
+
# request, so it is dropped.
|
|
769
|
+
if generation != self._generation:
|
|
770
|
+
self._stale_dropped_count += 1
|
|
771
|
+
return
|
|
772
|
+
|
|
773
|
+
resp_body_b64 = base64.b64encode(resp.content).decode() if resp.content else ""
|
|
774
|
+
# Serialize as an ORDERED LIST of pairs (not a dict): a response can carry several
|
|
775
|
+
# Set-Cookie headers (login/refresh emit access_token + refresh_token), and a dict would
|
|
776
|
+
# collapse them into one comma-joined value the browser can't parse, so the refresh
|
|
777
|
+
# cookie never reaches the browser and the session dies at the access token's hard cap.
|
|
778
|
+
# multi_items() keeps each header separate. Drop content-length; the relay recomputes it.
|
|
779
|
+
_skip = {"transfer-encoding", "connection", "keep-alive", "content-length"}
|
|
780
|
+
resp_headers = [
|
|
781
|
+
[k, v] for k, v in resp.headers.multi_items()
|
|
782
|
+
if k.lower() not in _skip
|
|
783
|
+
]
|
|
784
|
+
await self._send(self._ws, {
|
|
785
|
+
"type": "http.response",
|
|
786
|
+
"payload": {
|
|
787
|
+
"id": request_id,
|
|
788
|
+
"status": resp.status_code,
|
|
789
|
+
"headers": resp_headers,
|
|
790
|
+
"body_b64": resp_body_b64,
|
|
791
|
+
},
|
|
792
|
+
})
|
|
643
793
|
|
|
644
794
|
async def send_message(self, msg_type: str, **payload) -> None:
|
|
645
795
|
"""Send a JSON message over the active WS connection.
|
|
@@ -652,7 +802,12 @@ class GatewayClient:
|
|
|
652
802
|
|
|
653
803
|
@staticmethod
|
|
654
804
|
async def _send(ws, message: dict) -> None:
|
|
655
|
-
|
|
805
|
+
# Bound the send: a websocket send awaits until the frame is handed to the transport, and a
|
|
806
|
+
# stalled or backpressured peer would otherwise block it forever, pinning the proxy task and
|
|
807
|
+
# its relay slot. On the deadline the send is cancelled and TimeoutError surfaces to the
|
|
808
|
+
# caller, which lets the wedged socket be torn down and rebuilt. asyncio.wait_for, not
|
|
809
|
+
# asyncio.timeout: the latter is 3.11+ and this package supports Python >=3.10.
|
|
810
|
+
await asyncio.wait_for(ws.send(json.dumps(message)), _SEND_DEADLINE)
|
|
656
811
|
|
|
657
812
|
|
|
658
813
|
# Module-level singleton — set by main.py lifespan
|
|
@@ -337,8 +337,11 @@ default_modules/celerp-docs/tests/test_inventory_account_reconciliation.py
|
|
|
337
337
|
default_modules/celerp-docs/tests/test_landed_receive.py
|
|
338
338
|
default_modules/celerp-docs/tests/test_line_delete_persist.py
|
|
339
339
|
default_modules/celerp-docs/tests/test_line_identifier.py
|
|
340
|
+
default_modules/celerp-docs/tests/test_line_page_patch_truncate.py
|
|
340
341
|
default_modules/celerp-docs/tests/test_list_concurrency.py
|
|
341
342
|
default_modules/celerp-docs/tests/test_list_outcome_concurrency.py
|
|
343
|
+
default_modules/celerp-docs/tests/test_list_page_no_full_state.py
|
|
344
|
+
default_modules/celerp-docs/tests/test_list_query_pushdown.py
|
|
342
345
|
default_modules/celerp-docs/tests/test_memo_close.py
|
|
343
346
|
default_modules/celerp-docs/tests/test_memo_close_projection.py
|
|
344
347
|
default_modules/celerp-docs/tests/test_memo_close_review_fixes.py
|
|
@@ -344,8 +344,11 @@
|
|
|
344
344
|
"default_modules/celerp-docs/tests/test_landed_receive.py",
|
|
345
345
|
"default_modules/celerp-docs/tests/test_line_delete_persist.py",
|
|
346
346
|
"default_modules/celerp-docs/tests/test_line_identifier.py",
|
|
347
|
+
"default_modules/celerp-docs/tests/test_line_page_patch_truncate.py",
|
|
347
348
|
"default_modules/celerp-docs/tests/test_list_concurrency.py",
|
|
348
349
|
"default_modules/celerp-docs/tests/test_list_outcome_concurrency.py",
|
|
350
|
+
"default_modules/celerp-docs/tests/test_list_page_no_full_state.py",
|
|
351
|
+
"default_modules/celerp-docs/tests/test_list_query_pushdown.py",
|
|
349
352
|
"default_modules/celerp-docs/tests/test_memo_close.py",
|
|
350
353
|
"default_modules/celerp-docs/tests/test_memo_close_projection.py",
|
|
351
354
|
"default_modules/celerp-docs/tests/test_memo_close_review_fixes.py",
|
|
@@ -775,6 +778,7 @@
|
|
|
775
778
|
"tests/test_browser/test_ai_page.py",
|
|
776
779
|
"tests/test_browser/test_audit_scanner.py",
|
|
777
780
|
"tests/test_browser/test_auth_wall.py",
|
|
781
|
+
"tests/test_browser/test_backup_poll_single_flight.py",
|
|
778
782
|
"tests/test_browser/test_bulk_actions.py",
|
|
779
783
|
"tests/test_browser/test_bulk_attach_filter.py",
|
|
780
784
|
"tests/test_browser/test_clear_fields_ui.py",
|
|
@@ -828,6 +832,8 @@
|
|
|
828
832
|
"tests/test_browser/test_multi_company.py",
|
|
829
833
|
"tests/test_browser/test_nav_crawl.py",
|
|
830
834
|
"tests/test_browser/test_onboarding.py",
|
|
835
|
+
"tests/test_browser/test_poll_wedge_recovery.py",
|
|
836
|
+
"tests/test_browser/test_post318_stability.py",
|
|
831
837
|
"tests/test_browser/test_production_block_filters.py",
|
|
832
838
|
"tests/test_browser/test_production_order.py",
|
|
833
839
|
"tests/test_browser/test_reorder_digest_upsell.py",
|
|
@@ -870,6 +876,7 @@
|
|
|
870
876
|
"tests/test_connectors_sync_format.py",
|
|
871
877
|
"tests/test_contact_search_options.py",
|
|
872
878
|
"tests/test_crm_restructure.py",
|
|
879
|
+
"tests/test_csv_export_streaming.py",
|
|
873
880
|
"tests/test_dashboard_charts.py",
|
|
874
881
|
"tests/test_default_modules_boot.py",
|
|
875
882
|
"tests/test_demo_prices.py",
|
|
@@ -895,7 +902,9 @@
|
|
|
895
902
|
"tests/test_gateway/test_client.py",
|
|
896
903
|
"tests/test_gateway/test_feature_flags_state.py",
|
|
897
904
|
"tests/test_gateway/test_lazy_tunnel.py",
|
|
905
|
+
"tests/test_gateway/test_proxy_lifecycle.py",
|
|
898
906
|
"tests/test_gateway/test_reconnect_rebuild.py",
|
|
907
|
+
"tests/test_gateway/test_send_deadline_py310.py",
|
|
899
908
|
"tests/test_gateway/test_session_gate.py",
|
|
900
909
|
"tests/test_gateway/test_state.py",
|
|
901
910
|
"tests/test_holdings.py",
|
|
@@ -1043,6 +1052,8 @@
|
|
|
1043
1052
|
"tests/test_routers/test_address_card.py",
|
|
1044
1053
|
"tests/test_routers/test_auth.py",
|
|
1045
1054
|
"tests/test_routers/test_backup.py",
|
|
1055
|
+
"tests/test_routers/test_backup_active_503.py",
|
|
1056
|
+
"tests/test_routers/test_backup_active_state.py",
|
|
1046
1057
|
"tests/test_routers/test_bulk_payment_route_toast.py",
|
|
1047
1058
|
"tests/test_routers/test_cloud_relay.py",
|
|
1048
1059
|
"tests/test_routers/test_companies.py",
|
|
@@ -1077,6 +1088,8 @@
|
|
|
1077
1088
|
"tests/test_routers/test_items_metadata.py",
|
|
1078
1089
|
"tests/test_routers/test_ledger.py",
|
|
1079
1090
|
"tests/test_routers/test_list_detail_metadata_fanout.py",
|
|
1091
|
+
"tests/test_routers/test_list_detail_pagination.py",
|
|
1092
|
+
"tests/test_routers/test_list_detail_roundtrips.py",
|
|
1080
1093
|
"tests/test_routers/test_lists.py",
|
|
1081
1094
|
"tests/test_routers/test_monetary_precision.py",
|
|
1082
1095
|
"tests/test_routers/test_multicurrency_docs.py",
|
|
@@ -17,7 +17,16 @@ def _recalc_list_totals(state: dict) -> dict:
|
|
|
17
17
|
"""
|
|
18
18
|
currency = state.get("currency")
|
|
19
19
|
items = state.get("line_items", [])
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
def _li_amount(i: dict):
|
|
22
|
+
# An explicit line_total wins (it may be a per-line discount below quantity*unit_price);
|
|
23
|
+
# otherwise fall back to quantity*unit_price so a priced line still contributes.
|
|
24
|
+
lt = i.get("line_total")
|
|
25
|
+
if lt not in (None, ""):
|
|
26
|
+
return to_decimal(lt or 0)
|
|
27
|
+
return to_decimal(i.get("quantity", 0) or 0) * to_decimal(i.get("unit_price", 0) or 0)
|
|
28
|
+
|
|
29
|
+
subtotal = round_money(sum((_li_amount(i) for i in items), to_decimal(0)), currency)
|
|
21
30
|
state["subtotal"] = to_stored_float(subtotal)
|
|
22
31
|
|
|
23
32
|
discount = to_decimal(state.get("discount", 0) or 0)
|
|
@@ -28,7 +37,7 @@ def _recalc_list_totals(state: dict) -> dict:
|
|
|
28
37
|
taxable = subtotal - discount_amount
|
|
29
38
|
# Use per-line tax rates if present; fall back to header tax rate.
|
|
30
39
|
per_line_tax = sum(
|
|
31
|
-
(
|
|
40
|
+
(_li_amount(i) * to_decimal(i.get("tax_rate", 0) or 0) / 100 for i in items),
|
|
32
41
|
to_decimal(0),
|
|
33
42
|
)
|
|
34
43
|
if per_line_tax:
|